1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2003-2010, International Business Machines 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* file name: convtest.cpp 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* encoding: US-ASCII 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* tab size: 8 (not used) 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* indentation:4 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created on: 2003jul15 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created by: Markus W. Scherer 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Test file for data-driven conversion tests. 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_LEGACY_CONVERSION 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Note: Turning off all of convtest.cpp if !UCONFIG_NO_LEGACY_CONVERSION 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * is slightly unnecessary - it removes tests for Unicode charsets 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * like UTF-8 that should work. 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * However, there is no easy way for the test to detect whether a test case 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * is for a Unicode charset, so it would be difficult to only exclude those. 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Also, regular testing of ICU is done with all modules on, therefore 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * not testing conversion for a custom configuration like this should be ok. 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ucnv.h" 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/unistr.h" 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/parsepos.h" 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uniset.h" 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h" 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ures.h" 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "convtest.h" 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/tstdtmod.h" 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <string.h> 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdlib.h> 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)enum { 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // characters used in test data for callbacks 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) SUB_CB='?', 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) SKIP_CB='0', 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) STOP_CB='.', 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ESC_CB='&' 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::ConversionTest() { 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode=U_ZERO_ERROR; 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) utf8Cnv=ucnv_open("UTF-8", &errorCode); 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_setToUCallBack(utf8Cnv, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, NULL, &errorCode); 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("unable to open UTF-8 converter"); 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::~ConversionTest() { 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_close(utf8Cnv); 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) { 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (exec) logln("TestSuite ConversionTest: "); 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch (index) { 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FILE_IO 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0: name="TestToUnicode"; if (exec) TestToUnicode(); break; 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 1: name="TestFromUnicode"; if (exec) TestFromUnicode(); break; 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 2: name="TestGetUnicodeSet"; if (exec) TestGetUnicodeSet(); break; 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0: 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 1: 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 2: name="skip"; break; 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 3: name="TestGetUnicodeSet2"; if (exec) TestGetUnicodeSet2(); break; 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: name=""; break; //needed to end loop 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// test data interface ----------------------------------------------------- *** 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::TestToUnicode() { 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ConversionCase cc; 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char charset[100], cbopt[4]; 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *option; 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString s, unicode; 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t offsetsLength; 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterToUCallback callback; 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TestDataModule *dataModule; 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TestData *testData; 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const DataMap *testCase; 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode; 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dataModule=TestDataModule::getTestDataModule("conversion", *this, errorCode); 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(errorCode)) { 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) testData=dataModule->createTestData("toUnicode", errorCode); 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(errorCode)) { 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; testData->nextCase(testCase, errorCode); ++i) { 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error retrieving conversion/toUnicode test case %d - %s", 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, u_errorName(errorCode)); 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr=i; 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=testCase->getString("charset", errorCode); 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.extract(0, 0x7fffffff, charset, sizeof(charset), ""); 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.charset=charset; 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.bytes=testCase->getBinary(cc.bytesLength, "bytes", errorCode); 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unicode=testCase->getString("unicode", errorCode); 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.unicode=unicode.getBuffer(); 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.unicodeLength=unicode.length(); 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) offsetsLength=0; 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.offsets=testCase->getIntVector(offsetsLength, "offsets", errorCode); 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(offsetsLength==0) { 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.offsets=NULL; 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(offsetsLength!=unicode.length()) { 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("toUnicode[%d] unicode[%d] and offsets[%d] must have the same length", 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, unicode.length(), offsetsLength); 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ILLEGAL_ARGUMENT_ERROR; 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.finalFlush= 0!=testCase->getInt28("flush", errorCode); 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.fallbacks= 0!=testCase->getInt28("fallbacks", errorCode); 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=testCase->getString("errorCode", errorCode); 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s==UNICODE_STRING("invalid", 7)) { 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_INVALID_CHAR_FOUND; 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(s==UNICODE_STRING("illegal", 7)) { 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_ILLEGAL_CHAR_FOUND; 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(s==UNICODE_STRING("truncated", 9)) { 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_TRUNCATED_CHAR_FOUND; 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(s==UNICODE_STRING("illesc", 6)) { 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_ILLEGAL_ESCAPE_SEQUENCE; 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(s==UNICODE_STRING("unsuppesc", 9)) { 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_UNSUPPORTED_ESCAPE_SEQUENCE; 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_ZERO_ERROR; 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=testCase->getString("callback", errorCode); 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.extract(0, 0x7fffffff, cbopt, sizeof(cbopt), ""); 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.cbopt=cbopt; 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(cbopt[0]) { 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case SUB_CB: 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=UCNV_TO_U_CALLBACK_SUBSTITUTE; 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case SKIP_CB: 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=UCNV_TO_U_CALLBACK_SKIP; 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case STOP_CB: 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=UCNV_TO_U_CALLBACK_STOP; 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ESC_CB: 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=UCNV_TO_U_CALLBACK_ESCAPE; 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=NULL; 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) option=callback==NULL ? cbopt : cbopt+1; 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*option==0) { 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) option=NULL; 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.invalidChars=testCase->getBinary(cc.invalidLength, "invalidChars", errorCode); 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error parsing conversion/toUnicode test case %d - %s", 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, u_errorName(errorCode)); 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) logln("TestToUnicode[%d] %s", i, charset); 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ToUnicodeCase(cc, callback, option); 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete testData; 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete dataModule; 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dataerrln("Could not load test conversion data"); 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::TestFromUnicode() { 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ConversionCase cc; 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char charset[100], cbopt[4]; 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *option; 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString s, unicode, invalidUChars; 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t offsetsLength, index; 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterFromUCallback callback; 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TestDataModule *dataModule; 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TestData *testData; 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const DataMap *testCase; 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *p; 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode; 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i, length; 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dataModule=TestDataModule::getTestDataModule("conversion", *this, errorCode); 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(errorCode)) { 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) testData=dataModule->createTestData("fromUnicode", errorCode); 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(errorCode)) { 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; testData->nextCase(testCase, errorCode); ++i) { 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error retrieving conversion/fromUnicode test case %d - %s", 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, u_errorName(errorCode)); 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr=i; 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=testCase->getString("charset", errorCode); 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.extract(0, 0x7fffffff, charset, sizeof(charset), ""); 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.charset=charset; 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unicode=testCase->getString("unicode", errorCode); 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.unicode=unicode.getBuffer(); 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.unicodeLength=unicode.length(); 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.bytes=testCase->getBinary(cc.bytesLength, "bytes", errorCode); 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) offsetsLength=0; 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.offsets=testCase->getIntVector(offsetsLength, "offsets", errorCode); 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(offsetsLength==0) { 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.offsets=NULL; 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(offsetsLength!=cc.bytesLength) { 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("fromUnicode[%d] bytes[%d] and offsets[%d] must have the same length", 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, cc.bytesLength, offsetsLength); 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ILLEGAL_ARGUMENT_ERROR; 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.finalFlush= 0!=testCase->getInt28("flush", errorCode); 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.fallbacks= 0!=testCase->getInt28("fallbacks", errorCode); 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=testCase->getString("errorCode", errorCode); 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s==UNICODE_STRING("invalid", 7)) { 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_INVALID_CHAR_FOUND; 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(s==UNICODE_STRING("illegal", 7)) { 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_ILLEGAL_CHAR_FOUND; 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(s==UNICODE_STRING("truncated", 9)) { 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_TRUNCATED_CHAR_FOUND; 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.outErrorCode=U_ZERO_ERROR; 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=testCase->getString("callback", errorCode); 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.setSub=0; // default: no subchar 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((index=s.indexOf((UChar)0))>0) { 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // read NUL-separated subchar first, if any 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // copy the subchar from Latin-1 characters 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // start after the NUL 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) p=s.getTerminatedBuffer(); 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=index+1; 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) p+=length; 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=s.length()-length; 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length<=0 || length>=(int32_t)sizeof(cc.subchar)) { 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ILLEGAL_ARGUMENT_ERROR; 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t j; 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(j=0; j<length; ++j) { 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.subchar[j]=(char)p[j]; 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // NUL-terminate the subchar 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.subchar[j]=0; 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.setSub=1; 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // remove the NUL and subchar from s 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.truncate(index); 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if((index=s.indexOf((UChar)0x3d))>0) /* '=' */ { 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // read a substitution string, separated by an equal sign 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) p=s.getBuffer()+index+1; 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=s.length()-(index+1); 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length<0 || length>=LENGTHOF(cc.subString)) { 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ILLEGAL_ARGUMENT_ERROR; 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_memcpy(cc.subString, p, length); 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // NUL-terminate the subString 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.subString[length]=0; 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.setSub=-1; 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // remove the equal sign and subString from s 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.truncate(index); 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.extract(0, 0x7fffffff, cbopt, sizeof(cbopt), ""); 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.cbopt=cbopt; 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(cbopt[0]) { 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case SUB_CB: 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=UCNV_FROM_U_CALLBACK_SUBSTITUTE; 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case SKIP_CB: 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=UCNV_FROM_U_CALLBACK_SKIP; 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case STOP_CB: 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=UCNV_FROM_U_CALLBACK_STOP; 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ESC_CB: 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=UCNV_FROM_U_CALLBACK_ESCAPE; 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) callback=NULL; 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) option=callback==NULL ? cbopt : cbopt+1; 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*option==0) { 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) option=NULL; 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) invalidUChars=testCase->getString("invalidUChars", errorCode); 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.invalidUChars=invalidUChars.getBuffer(); 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.invalidLength=invalidUChars.length(); 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error parsing conversion/fromUnicode test case %d - %s", 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, u_errorName(errorCode)); 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) logln("TestFromUnicode[%d] %s", i, charset); 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FromUnicodeCase(cc, callback, option); 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete testData; 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete dataModule; 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dataerrln("Could not load test conversion data"); 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar ellipsis[]={ 0x2e, 0x2e, 0x2e }; 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::TestGetUnicodeSet() { 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char charset[100]; 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString s, map, mapnot; 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t which; 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ParsePosition pos; 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeSet cnvSet, mapSet, mapnotSet, diffSet; 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeSet *cnvSetPtr = &cnvSet; 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) LocalUConverterPointer cnv; 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TestDataModule *dataModule; 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TestData *testData; 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const DataMap *testCase; 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode; 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dataModule=TestDataModule::getTestDataModule("conversion", *this, errorCode); 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(errorCode)) { 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) testData=dataModule->createTestData("getUnicodeSet", errorCode); 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(errorCode)) { 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; testData->nextCase(testCase, errorCode); ++i) { 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error retrieving conversion/getUnicodeSet test case %d - %s", 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, u_errorName(errorCode)); 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=testCase->getString("charset", errorCode); 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.extract(0, 0x7fffffff, charset, sizeof(charset), ""); 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) map=testCase->getString("map", errorCode); 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mapnot=testCase->getString("mapnot", errorCode); 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) which=testCase->getInt28("which", errorCode); 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error parsing conversion/getUnicodeSet test case %d - %s", 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, u_errorName(errorCode)); 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // test this test case 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mapSet.clear(); 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mapnotSet.clear(); 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pos.setIndex(0); 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mapSet.applyPattern(map, pos, 0, NULL, errorCode); 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode) || pos.getIndex()!=map.length()) { 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error creating the map set for conversion/getUnicodeSet test case %d - %s\n" 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " error index %d index %d U+%04x", 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, u_errorName(errorCode), pos.getErrorIndex(), pos.getIndex(), map.char32At(pos.getIndex())); 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pos.setIndex(0); 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mapnotSet.applyPattern(mapnot, pos, 0, NULL, errorCode); 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode) || pos.getIndex()!=mapnot.length()) { 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error creating the mapnot set for conversion/getUnicodeSet test case %d - %s\n" 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " error index %d index %d U+%04x", 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i, u_errorName(errorCode), pos.getErrorIndex(), pos.getIndex(), mapnot.char32At(pos.getIndex())); 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) logln("TestGetUnicodeSet[%d] %s", i, charset); 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv.adoptInstead(cnv_open(charset, errorCode)); 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errcheckln(errorCode, "error opening \"%s\" for conversion/getUnicodeSet test case %d - %s", 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) charset, i, u_errorName(errorCode)); 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_getUnicodeSet(cnv.getAlias(), cnvSetPtr->toUSet(), (UConverterUnicodeSet)which, &errorCode); 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error in ucnv_getUnicodeSet(\"%s\") for conversion/getUnicodeSet test case %d - %s", 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) charset, i, u_errorName(errorCode)); 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // are there items that must be in cnvSet but are not? 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (diffSet=mapSet).removeAll(cnvSet); 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!diffSet.isEmpty()) { 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) diffSet.toPattern(s, TRUE); 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s.length()>100) { 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.replace(100, 0x7fffffff, ellipsis, LENGTHOF(ellipsis)); 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error: ucnv_getUnicodeSet(\"%s\") is missing items - conversion/getUnicodeSet test case %d", 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) charset, i); 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln(s); 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // are there items that must not be in cnvSet but are? 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (diffSet=mapnotSet).retainAll(cnvSet); 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!diffSet.isEmpty()) { 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) diffSet.toPattern(s, TRUE); 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s.length()>100) { 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.replace(100, 0x7fffffff, ellipsis, LENGTHOF(ellipsis)); 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error: ucnv_getUnicodeSet(\"%s\") contains unexpected items - conversion/getUnicodeSet test case %d", 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) charset, i); 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln(s); 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete testData; 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete dataModule; 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dataerrln("Could not load test conversion data"); 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_BEGIN 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void U_CALLCONV 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getUnicodeSetCallback(const void *context, 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterFromUnicodeArgs * /*fromUArgs*/, 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar* /*codeUnits*/, 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t /*length*/, 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 codePoint, 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterCallbackReason reason, 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(reason<=UCNV_IRREGULAR) { 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UnicodeSet *)context)->remove(codePoint); // the converter cannot convert this code point 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ZERO_ERROR; // skip 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } // else ignore the reset, close and clone calls. 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_END 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Compare ucnv_getUnicodeSet() with the set of characters that can be converted. 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::TestGetUnicodeSet2() { 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Build a string with all code points. 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 cpLimit; 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t s0Length; 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(quick) { 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cpLimit=s0Length=0x10000; // BMP only 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cpLimit=0x110000; 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s0Length=0x10000+0x200000; // BMP + surrogate pairs 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *s0=new UChar[s0Length]; 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s0==NULL) { 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *s=s0; 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c; 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar c2; 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // low BMP 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(c=0; c<=0xd7ff; ++c) { 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *s++=(UChar)c; 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // trail surrogates 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(c=0xdc00; c<=0xdfff; ++c) { 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *s++=(UChar)c; 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // lead surrogates 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // (after trails so that there is not even one surrogate pair in between) 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(c=0xd800; c<=0xdbff; ++c) { 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *s++=(UChar)c; 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // high BMP 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(c=0xe000; c<=0xffff; ++c) { 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *s++=(UChar)c; 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // supplementary code points = surrogate pairs 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cpLimit==0x110000) { 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(c=0xd800; c<=0xdbff; ++c) { 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(c2=0xdc00; c2<=0xdfff; ++c2) { 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *s++=(UChar)c; 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *s++=c2; 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) static const char *const cnvNames[]={ 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "UTF-8", 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "UTF-7", 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "UTF-16", 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "US-ASCII", 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "ISO-8859-1", 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "windows-1252", 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "Shift-JIS", 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "ibm-1390", // EBCDIC_STATEFUL table 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "ibm-16684", // DBCS-only extension table based on EBCDIC_STATEFUL table 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "HZ", 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "ISO-2022-JP", 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "JIS7", 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "ISO-2022-CN", 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "ISO-2022-CN-EXT", 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "LMBCS" 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }; 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) LocalUConverterPointer cnv; 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char buffer[1024]; 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; i<LENGTHOF(cnvNames); ++i) { 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode=U_ZERO_ERROR; 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv.adoptInstead(cnv_open(cnvNames[i], errorCode)); 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errcheckln(errorCode, "failed to open converter %s - %s", cnvNames[i], u_errorName(errorCode)); 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeSet expected; 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_setFromUCallBack(cnv.getAlias(), getUnicodeSetCallback, &expected, NULL, NULL, &errorCode); 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("failed to set the callback on converter %s - %s", cnvNames[i], u_errorName(errorCode)); 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterUnicodeSet which; 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(which=UCNV_ROUNDTRIP_SET; which<UCNV_SET_COUNT; which=(UConverterUnicodeSet)((int)which+1)) { 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(which==UCNV_ROUNDTRIP_AND_FALLBACK_SET) { 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_setFallback(cnv.getAlias(), TRUE); 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) expected.add(0, cpLimit-1); 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=s0; 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool flush; 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) do { 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *t=buffer; 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=(UBool)(s==s0+s0Length); 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_fromUnicode(cnv.getAlias(), &t, buffer+sizeof(buffer), (const UChar **)&s, s0+s0Length, NULL, flush, &errorCode); 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(errorCode==U_BUFFER_OVERFLOW_ERROR) { 583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; // unexpected error, should not occur 587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } while(!flush); 590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeSet set; 591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_getUnicodeSet(cnv.getAlias(), set.toUSet(), which, &errorCode); 592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cpLimit<0x110000) { 593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) set.remove(cpLimit, 0x10ffff); 594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(which==UCNV_ROUNDTRIP_SET) { 596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ignore PUA code points because they will be converted even if they 597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // are fallbacks and when other fallbacks are turned off, 598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // but ucnv_getUnicodeSet(UCNV_ROUNDTRIP_SET) delivers true roundtrips 599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) expected.remove(0xe000, 0xf8ff); 600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) expected.remove(0xf0000, 0xffffd); 601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) expected.remove(0x100000, 0x10fffd); 602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) set.remove(0xe000, 0xf8ff); 603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) set.remove(0xf0000, 0xffffd); 604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) set.remove(0x100000, 0x10fffd); 605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(set!=expected) { 607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // First try to see if we have different sets because ucnv_getUnicodeSet() 608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // added strings: The above conversion method does not tell us what strings might be convertible. 609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Remove strings from the set and compare again. 610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Unfortunately, there are no good, direct set methods for finding out whether there are strings 611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // in the set, nor for enumerating or removing just them. 612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Intersect all code points with the set. The intersection will not contain strings. 613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeSet temp(0, 0x10ffff); 614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) temp.retainAll(set); 615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) set=temp; 616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(set!=expected) { 618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeSet diffSet; 619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString out; 620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // are there items that must be in the set but are not? 622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (diffSet=expected).removeAll(set); 623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!diffSet.isEmpty()) { 624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) diffSet.toPattern(out, TRUE); 625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(out.length()>100) { 626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) out.replace(100, 0x7fffffff, ellipsis, LENGTHOF(ellipsis)); 627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error: ucnv_getUnicodeSet(\"%s\") is missing items - which set: %d", 629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnvNames[i], which); 630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln(out); 631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // are there items that must not be in the set but are? 634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (diffSet=set).removeAll(expected); 635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!diffSet.isEmpty()) { 636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) diffSet.toPattern(out, TRUE); 637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(out.length()>100) { 638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) out.replace(100, 0x7fffffff, ellipsis, LENGTHOF(ellipsis)); 639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("error: ucnv_getUnicodeSet(\"%s\") contains unexpected items - which set: %d", 641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnvNames[i], which); 642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln(out); 643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete [] s0; 649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// open testdata or ICU data converter ------------------------------------- *** 652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UConverter * 654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::cnv_open(const char *name, UErrorCode &errorCode) { 655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(name!=NULL && *name=='*') { 656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* loadTestData(): set the data directory */ 657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ucnv_openPackage(loadTestData(errorCode), name+1, &errorCode); 658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(name!=NULL && *name=='+') { 659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ucnv_open((name+1), &errorCode); 660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ucnv_open(name, &errorCode); 662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// output helpers ---------------------------------------------------------- *** 666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static inline char 668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)hexDigit(uint8_t digit) { 669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return digit<=9 ? (char)('0'+digit) : (char)('a'-10+digit); 670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char * 673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)printBytes(const uint8_t *bytes, int32_t length, char *out) { 674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint8_t b; 675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length>0) { 677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b=*bytes++; 678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --length; 679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=hexDigit((uint8_t)(b>>4)); 680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=hexDigit((uint8_t)(b&0xf)); 681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(length>0) { 684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b=*bytes++; 685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --length; 686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=' '; 687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=hexDigit((uint8_t)(b>>4)); 688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=hexDigit((uint8_t)(b&0xf)); 689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=0; 691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return out; 692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char * 695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)printUnicode(const UChar *unicode, int32_t length, char *out) { 696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c; 697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; i<length;) { 700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(i>0) { 701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=' '; 702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_NEXT(unicode, i, length, c); 704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // write 4..6 digits 705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(c>=0x100000) { 706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++='1'; 707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(c>=0x10000) { 709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=hexDigit((uint8_t)((c>>16)&0xf)); 710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=hexDigit((uint8_t)((c>>12)&0xf)); 712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=hexDigit((uint8_t)((c>>8)&0xf)); 713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=hexDigit((uint8_t)((c>>4)&0xf)); 714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=hexDigit((uint8_t)(c&0xf)); 715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=0; 717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return out; 718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char * 721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)printOffsets(const int32_t *offsets, int32_t length, char *out) { 722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i, o, d; 723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(offsets==NULL) { 725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=0; 726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; i<length; ++i) { 729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(i>0) { 730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=' '; 731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) o=offsets[i]; 733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // print all offsets with 2 characters each (-x, -9..99, xx) 735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(o<-9) { 736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++='-'; 737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++='x'; 738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(o<0) { 739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++='-'; 740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=(char)('0'-o); 741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(o<=99) { 742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=(d=o/10)==0 ? ' ' : (char)('0'+d); 743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=(char)('0'+o%10); 744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else /* o>99 */ { 745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++='x'; 746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++='x'; 747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *out++=0; 750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return out; 751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// toUnicode test worker functions ----------------------------------------- *** 754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)stepToUnicode(ConversionCase &cc, UConverter *cnv, 757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *result, int32_t resultCapacity, 758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *resultOffsets, /* also resultCapacity */ 759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t step, 760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *source, *sourceLimit, *bytesLimit; 762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *target, *targetLimit, *resultLimit; 763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool flush; 764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) source=(const char *)cc.bytes; 766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target=result; 767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bytesLimit=source+cc.bytesLength; 768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLimit=result+resultCapacity; 769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(step>=0) { 771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // call ucnv_toUnicode() with in/out buffers no larger than (step) at a time 772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // move only one buffer (in vs. out) at a time to be extra mean 773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step==0 performs bulk conversion and generates offsets 774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // initialize the partial limits for the loop 776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(step==0) { 777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // use the entire buffers 778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=bytesLimit; 779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=resultLimit; 780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=cc.finalFlush; 781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // start with empty partial buffers 783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=source; 784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=target; 785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=FALSE; 786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // output offsets only for bulk conversion 788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultOffsets=NULL; 789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // resetting the opposite conversion direction must not affect this one 793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetFromUnicode(cnv); 794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // convert 796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_toUnicode(cnv, 797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &target, targetLimit, 798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &source, sourceLimit, 799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultOffsets, 800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush, pErrorCode); 801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // check pointers and errors 803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source>sourceLimit || target>targetLimit) { 804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(target!=targetLimit) { 808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // buffer overflow must only be set when the target is filled 809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(targetLimit==resultLimit) { 812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // not just a partial overflow 813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the partial target is filled, set a new limit, reset the error and continue 817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=(resultLimit-target)>=step ? target+step : resultLimit; 818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ZERO_ERROR; 819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(U_FAILURE(*pErrorCode)) { 820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // some other error occurred, done 821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source!=sourceLimit) { 824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // when no error occurs, then the input must be consumed 825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceLimit==bytesLimit) { 830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we are done 831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the partial conversion succeeded, set a new limit and continue 835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=(bytesLimit-source)>=step ? source+step : bytesLimit; 836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=(UBool)(cc.finalFlush && sourceLimit==bytesLimit); 837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else /* step<0 */ { 840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * step==-1: call only ucnv_getNextUChar() 842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * otherwise alternate between ucnv_toUnicode() and ucnv_getNextUChar() 843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if step==-2 or -3, then give ucnv_toUnicode() the whole remaining input, 844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * else give it at most (-step-2)/2 bytes 845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c; 847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // end the loop by getting an index out of bounds error 849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // resetting the opposite conversion direction must not affect this one 851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetFromUnicode(cnv); 852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // convert 854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((step&1)!=0 /* odd: -1, -3, -5, ... */) { 855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=source; // use sourceLimit not as a real limit 856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // but to remember the pre-getNextUChar source pointer 857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c=ucnv_getNextUChar(cnv, &source, bytesLimit, pErrorCode); 858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // check pointers and errors 860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*pErrorCode==U_INDEX_OUTOFBOUNDS_ERROR) { 861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source!=bytesLimit) { 862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ZERO_ERROR; 865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(U_FAILURE(*pErrorCode)) { 868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // source may not move if c is from previous overflow 871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(target==resultLimit) { 873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(c<=0xffff) { 877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *target++=(UChar)c; 878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *target++=U16_LEAD(c); 880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(target==resultLimit) { 881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *target++=U16_TRAIL(c); 885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // alternate between -n-1 and -n but leave -1 alone 888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(step<-1) { 889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++step; 890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else /* step is even */ { 892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // allow only one UChar output 893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=target<resultLimit ? target+1 : resultLimit; 894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // as with ucnv_getNextUChar(), we always flush (if we go to bytesLimit) 896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // and never output offsets 897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(step==-2) { 898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=bytesLimit; 899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=source+(-step-2)/2; 901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceLimit>bytesLimit) { 902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=bytesLimit; 903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_toUnicode(cnv, 907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &target, targetLimit, 908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &source, sourceLimit, 909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, (UBool)(sourceLimit==bytesLimit), pErrorCode); 910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // check pointers and errors 912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(target!=targetLimit) { 914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // buffer overflow must only be set when the target is filled 915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(targetLimit==resultLimit) { 918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // not just a partial overflow 919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the partial target is filled, set a new limit and continue 923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ZERO_ERROR; 924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(U_FAILURE(*pErrorCode)) { 925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // some other error occurred, done 926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source!=sourceLimit) { 929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // when no error occurs, then the input must be consumed 930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we are done (flush==TRUE) but we continue, to get the index out of bounds error above 935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --step; 938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (int32_t)(target-result); 943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool 946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::ToUnicodeCase(ConversionCase &cc, UConverterToUCallback callback, const char *option) { 947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // open the converter 948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) IcuTestErrorCode errorCode(*this, "ToUnicodeCase"); 949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) LocalUConverterPointer cnv(cnv_open(cc.charset, errorCode)); 950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(errorCode.isFailure()) { 951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errcheckln(errorCode, "toUnicode[%d](%s cb=\"%s\" fb=%d flush=%d) ucnv_open() failed - %s", 952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, errorCode.errorName()); 953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode.reset(); 954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // set the callback 958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(callback!=NULL) { 959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_setToUCallBack(cnv.getAlias(), callback, option, NULL, NULL, errorCode); 960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("toUnicode[%d](%s cb=\"%s\" fb=%d flush=%d) ucnv_setToUCallBack() failed - %s", 962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, u_errorName(errorCode)); 963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultOffsets[256]; 968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[256]; 969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultLength; 970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool ok; 971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) static const struct { 973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t step; 974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *name; 975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } steps[]={ 976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 0, "bulk" }, // must be first for offsets to be checked 977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1, "step=1" }, 978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 3, "step=3" }, 979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 7, "step=7" }, 980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { -1, "getNext" }, 981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { -2, "toU(bulk)+getNext" }, 982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { -3, "getNext+toU(bulk)" }, 983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { -4, "toU(1)+getNext" }, 984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { -5, "getNext+toU(1)" }, 985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { -12, "toU(5)+getNext" }, 986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { -13, "getNext+toU(5)" }, 987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }; 988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i, step; 989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ok=TRUE; 991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; i<LENGTHOF(steps) && ok; ++i) { 992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) step=steps[i].step; 993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(step<0 && !cc.finalFlush) { 994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // skip ucnv_getNextUChar() if !finalFlush because 995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ucnv_getNextUChar() always implies flush 996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(step!=0) { 999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // bulk test is first, then offsets are not checked any more 1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.offsets=NULL; 1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memset(resultOffsets, -1, LENGTHOF(resultOffsets)); 1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memset(result, -1, LENGTHOF(result)); 1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode.reset(); 1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLength=stepToUnicode(cc, cnv.getAlias(), 1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result, LENGTHOF(result), 1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) step==0 ? resultOffsets : NULL, 1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) step, errorCode); 1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ok=checkToUnicode( 1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc, cnv.getAlias(), steps[i].name, 1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result, resultLength, 1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.offsets!=NULL ? resultOffsets : NULL, 1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode); 1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(errorCode.isFailure() || !cc.finalFlush) { 1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // reset if an error occurred or we did not flush 1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // otherwise do nothing to make sure that flushing resets 1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetToUnicode(cnv.getAlias()); 1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (cc.offsets != NULL && resultOffsets[resultLength] != -1) { 1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("toUnicode[%d](%s) Conversion wrote too much to offsets at index %d", 1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, resultLength); 1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result[resultLength] != (UChar)-1) { 1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("toUnicode[%d](%s) Conversion wrote too much to result at index %d", 1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, resultLength); 1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // not a real loop, just a convenience for breaking out of the block 1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ok && cc.finalFlush) { 1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // test ucnv_toUChars() 1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memset(result, 0, sizeof(result)); 1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode.reset(); 1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLength=ucnv_toUChars(cnv.getAlias(), 1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result, LENGTHOF(result), 1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (const char *)cc.bytes, cc.bytesLength, 1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode); 1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ok=checkToUnicode( 1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc, cnv.getAlias(), "toUChars", 1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result, resultLength, 1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode); 1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!ok) { 1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // test preflighting 1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // keep the correct result for simple checking 1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode.reset(); 1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLength=ucnv_toUChars(cnv.getAlias(), 1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 0, 1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (const char *)cc.bytes, cc.bytesLength, 1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode); 1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(errorCode.get()==U_STRING_NOT_TERMINATED_WARNING || errorCode.get()==U_BUFFER_OVERFLOW_ERROR) { 1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode.reset(); 1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ok=checkToUnicode( 1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc, cnv.getAlias(), "preflight toUChars", 1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result, resultLength, 1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode); 1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode.reset(); // all errors have already been reported 1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ok; 1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool 1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::checkToUnicode(ConversionCase &cc, UConverter *cnv, const char *name, 1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *result, int32_t resultLength, 1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const int32_t *resultOffsets, 1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode resultErrorCode) { 1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char resultInvalidChars[8]; 1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int8_t resultInvalidLength; 1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode; 1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *msg; 1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // reset the message; NULL will mean "ok" 1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg=NULL; 1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultInvalidLength=sizeof(resultInvalidChars); 1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_getInvalidChars(cnv, resultInvalidChars, &resultInvalidLength, &errorCode); 1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("toUnicode[%d](%s cb=\"%s\" fb=%d flush=%d %s) ucnv_getInvalidChars() failed - %s", 1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, name, u_errorName(errorCode)); 1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // check everything that might have gone wrong 1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cc.unicodeLength!=resultLength) { 1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong result length"; 1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(0!=u_memcmp(cc.unicode, result, cc.unicodeLength)) { 1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong result string"; 1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(cc.offsets!=NULL && 0!=memcmp(cc.offsets, resultOffsets, cc.unicodeLength*sizeof(*cc.offsets))) { 1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong offsets"; 1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(cc.outErrorCode!=resultErrorCode) { 1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong error code"; 1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(cc.invalidLength!=resultInvalidLength) { 1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong length of last invalid input"; 1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(0!=memcmp(cc.invalidChars, resultInvalidChars, cc.invalidLength)) { 1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong last invalid input"; 1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(msg==NULL) { 1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char buffer[2000]; // one buffer for all strings 1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *s, *bytesString, *unicodeString, *resultString, 1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *offsetsString, *resultOffsetsString, 1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *invalidCharsString, *resultInvalidCharsString; 1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bytesString=s=buffer; 1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printBytes(cc.bytes, cc.bytesLength, bytesString); 1120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printUnicode(cc.unicode, cc.unicodeLength, unicodeString=s); 1121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printUnicode(result, resultLength, resultString=s); 1122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printOffsets(cc.offsets, cc.unicodeLength, offsetsString=s); 1123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printOffsets(resultOffsets, resultLength, resultOffsetsString=s); 1124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printBytes(cc.invalidChars, cc.invalidLength, invalidCharsString=s); 1125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printBytes((uint8_t *)resultInvalidChars, resultInvalidLength, resultInvalidCharsString=s); 1126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((s-buffer)>(int32_t)sizeof(buffer)) { 1128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("toUnicode[%d](%s cb=\"%s\" fb=%d flush=%d %s) fatal error: checkToUnicode() test output buffer overflow writing %d chars\n", 1129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, name, (int)(s-buffer)); 1130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) exit(1); 1131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("toUnicode[%d](%s cb=\"%s\" fb=%d flush=%d %s) failed: %s\n" 1134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " bytes <%s>[%d]\n" 1135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " expected <%s>[%d]\n" 1136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " result <%s>[%d]\n" 1137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " offsets <%s>\n" 1138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " result offsets <%s>\n" 1139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " error code expected %s got %s\n" 1140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " invalidChars expected <%s> got <%s>\n", 1141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, name, msg, 1142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bytesString, cc.bytesLength, 1143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unicodeString, cc.unicodeLength, 1144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultString, resultLength, 1145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) offsetsString, 1146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultOffsetsString, 1147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_errorName(cc.outErrorCode), u_errorName(resultErrorCode), 1148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) invalidCharsString, resultInvalidCharsString); 1149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 1151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// fromUnicode test worker functions --------------------------------------- *** 1155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 1157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)stepFromUTF8(ConversionCase &cc, 1158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter *utf8Cnv, UConverter *cnv, 1159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *result, int32_t resultCapacity, 1160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t step, 1161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 1162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *source, *sourceLimit, *utf8Limit; 1163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar pivotBuffer[32]; 1164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *pivotSource, *pivotTarget, *pivotLimit; 1165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *target, *targetLimit, *resultLimit; 1166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool flush; 1167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) source=cc.utf8; 1169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pivotSource=pivotTarget=pivotBuffer; 1170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target=result; 1171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) utf8Limit=source+cc.utf8Length; 1172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLimit=result+resultCapacity; 1173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // call ucnv_convertEx() with in/out buffers no larger than (step) at a time 1175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // move only one buffer (in vs. out) at a time to be extra mean 1176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step==0 performs bulk conversion 1177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // initialize the partial limits for the loop 1179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(step==0) { 1180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // use the entire buffers 1181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=utf8Limit; 1182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=resultLimit; 1183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=cc.finalFlush; 1184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pivotLimit=pivotBuffer+LENGTHOF(pivotBuffer); 1186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // start with empty partial buffers 1188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=source; 1189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=target; 1190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=FALSE; 1191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // empty pivot is not allowed, make it of length step 1193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pivotLimit=pivotBuffer+step; 1194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 1197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // resetting the opposite conversion direction must not affect this one 1198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetFromUnicode(utf8Cnv); 1199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetToUnicode(cnv); 1200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // convert 1202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_convertEx(cnv, utf8Cnv, 1203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &target, targetLimit, 1204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &source, sourceLimit, 1205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pivotBuffer, &pivotSource, &pivotTarget, pivotLimit, 1206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FALSE, flush, pErrorCode); 1207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // check pointers and errors 1209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source>sourceLimit || target>targetLimit) { 1210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 1211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 1213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(target!=targetLimit) { 1214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // buffer overflow must only be set when the target is filled 1215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 1216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(targetLimit==resultLimit) { 1218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // not just a partial overflow 1219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the partial target is filled, set a new limit, reset the error and continue 1223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=(resultLimit-target)>=step ? target+step : resultLimit; 1224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ZERO_ERROR; 1225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(U_FAILURE(*pErrorCode)) { 1226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pivotSource==pivotBuffer) { 1227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // toUnicode error, should not occur 1228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // toUnicode errors are tested in cintltst TestConvertExFromUTF8() 1229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // fromUnicode error 1232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // some other error occurred, done 1233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source!=sourceLimit) { 1237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // when no error occurs, then the input must be consumed 1238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 1239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceLimit==utf8Limit) { 1243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we are done 1244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*pErrorCode==U_STRING_NOT_TERMINATED_WARNING) { 1245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ucnv_convertEx() warns about not terminating the output 1246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // but ucnv_fromUnicode() does not and so 1247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // checkFromUnicode() does not expect it 1248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ZERO_ERROR; 1249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the partial conversion succeeded, set a new limit and continue 1254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=(utf8Limit-source)>=step ? source+step : utf8Limit; 1255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=(UBool)(cc.finalFlush && sourceLimit==utf8Limit); 1256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (int32_t)(target-result); 1260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 1263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)stepFromUnicode(ConversionCase &cc, UConverter *cnv, 1264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *result, int32_t resultCapacity, 1265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *resultOffsets, /* also resultCapacity */ 1266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t step, 1267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 1268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *source, *sourceLimit, *unicodeLimit; 1269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *target, *targetLimit, *resultLimit; 1270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool flush; 1271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) source=cc.unicode; 1273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target=result; 1274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unicodeLimit=source+cc.unicodeLength; 1275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLimit=result+resultCapacity; 1276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // call ucnv_fromUnicode() with in/out buffers no larger than (step) at a time 1278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // move only one buffer (in vs. out) at a time to be extra mean 1279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step==0 performs bulk conversion and generates offsets 1280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // initialize the partial limits for the loop 1282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(step==0) { 1283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // use the entire buffers 1284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=unicodeLimit; 1285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=resultLimit; 1286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=cc.finalFlush; 1287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // start with empty partial buffers 1289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=source; 1290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=target; 1291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=FALSE; 1292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // output offsets only for bulk conversion 1294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultOffsets=NULL; 1295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 1298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // resetting the opposite conversion direction must not affect this one 1299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetToUnicode(cnv); 1300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // convert 1302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_fromUnicode(cnv, 1303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &target, targetLimit, 1304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &source, sourceLimit, 1305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultOffsets, 1306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush, pErrorCode); 1307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // check pointers and errors 1309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source>sourceLimit || target>targetLimit) { 1310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 1311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 1313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(target!=targetLimit) { 1314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // buffer overflow must only be set when the target is filled 1315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 1316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(targetLimit==resultLimit) { 1318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // not just a partial overflow 1319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the partial target is filled, set a new limit, reset the error and continue 1323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLimit=(resultLimit-target)>=step ? target+step : resultLimit; 1324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ZERO_ERROR; 1325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(U_FAILURE(*pErrorCode)) { 1326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // some other error occurred, done 1327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source!=sourceLimit) { 1330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // when no error occurs, then the input must be consumed 1331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 1332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceLimit==unicodeLimit) { 1336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we are done 1337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the partial conversion succeeded, set a new limit and continue 1341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceLimit=(unicodeLimit-source)>=step ? source+step : unicodeLimit; 1342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) flush=(UBool)(cc.finalFlush && sourceLimit==unicodeLimit); 1343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (int32_t)(target-result); 1347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool 1350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::FromUnicodeCase(ConversionCase &cc, UConverterFromUCallback callback, const char *option) { 1351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter *cnv; 1352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode; 1353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // open the converter 1355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 1356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv=cnv_open(cc.charset, errorCode); 1357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 1358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errcheckln(errorCode, "fromUnicode[%d](%s cb=\"%s\" fb=%d flush=%d) ucnv_open() failed - %s", 1359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, u_errorName(errorCode)); 1360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 1361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetToUnicode(utf8Cnv); 1363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // set the callback 1365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(callback!=NULL) { 1366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_setFromUCallBack(cnv, callback, option, NULL, NULL, &errorCode); 1367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 1368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("fromUnicode[%d](%s cb=\"%s\" fb=%d flush=%d) ucnv_setFromUCallBack() failed - %s", 1369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, u_errorName(errorCode)); 1370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_close(cnv); 1371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 1372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // set the fallbacks flag 1376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO change with Jitterbug 2401, then add a similar call for toUnicode too 1377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_setFallback(cnv, cc.fallbacks); 1378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // set the subchar 1380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length; 1381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cc.setSub>0) { 1383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=(int32_t)strlen(cc.subchar); 1384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_setSubstChars(cnv, cc.subchar, (int8_t)length, &errorCode); 1385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 1386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("fromUnicode[%d](%s cb=\"%s\" fb=%d flush=%d) ucnv_setSubstChars() failed - %s", 1387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, u_errorName(errorCode)); 1388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_close(cnv); 1389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 1390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(cc.setSub<0) { 1392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_setSubstString(cnv, cc.subString, -1, &errorCode); 1393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 1394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("fromUnicode[%d](%s cb=\"%s\" fb=%d flush=%d) ucnv_setSubstString() failed - %s", 1395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, u_errorName(errorCode)); 1396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_close(cnv); 1397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 1398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // convert unicode to utf8 1402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char utf8[256]; 1403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.utf8=utf8; 1404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_strToUTF8(utf8, LENGTHOF(utf8), &cc.utf8Length, 1405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.unicode, cc.unicodeLength, 1406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &errorCode); 1407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 1408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // skip UTF-8 testing of a string with an unpaired surrogate, 1409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // or of one that's too long 1410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // toUnicode errors are tested in cintltst TestConvertExFromUTF8() 1411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.utf8Length=-1; 1412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultOffsets[256]; 1415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char result[256]; 1416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultLength; 1417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool ok; 1418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) static const struct { 1420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t step; 1421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *name, *utf8Name; 1422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } steps[]={ 1423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 0, "bulk", "utf8" }, // must be first for offsets to be checked 1424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1, "step=1", "utf8 step=1" }, 1425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 3, "step=3", "utf8 step=3" }, 1426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 7, "step=7", "utf8 step=7" } 1427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }; 1428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i, step; 1429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ok=TRUE; 1431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; i<LENGTHOF(steps) && ok; ++i) { 1432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) step=steps[i].step; 1433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memset(resultOffsets, -1, LENGTHOF(resultOffsets)); 1434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memset(result, -1, LENGTHOF(result)); 1435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 1436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLength=stepFromUnicode(cc, cnv, 1437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result, LENGTHOF(result), 1438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) step==0 ? resultOffsets : NULL, 1439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) step, &errorCode); 1440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ok=checkFromUnicode( 1441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc, cnv, steps[i].name, 1442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (uint8_t *)result, resultLength, 1443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.offsets!=NULL ? resultOffsets : NULL, 1444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode); 1445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode) || !cc.finalFlush) { 1446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // reset if an error occurred or we did not flush 1447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // otherwise do nothing to make sure that flushing resets 1448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetFromUnicode(cnv); 1449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (resultOffsets[resultLength] != -1) { 1451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("fromUnicode[%d](%s) Conversion wrote too much to offsets at index %d", 1452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, resultLength); 1453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result[resultLength] != (char)-1) { 1455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("fromUnicode[%d](%s) Conversion wrote too much to result at index %d", 1456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, resultLength); 1457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // bulk test is first, then offsets are not checked any more 1460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.offsets=NULL; 1461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // test direct conversion from UTF-8 1463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cc.utf8Length>=0) { 1464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 1465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLength=stepFromUTF8(cc, utf8Cnv, cnv, 1466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result, LENGTHOF(result), 1467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) step, &errorCode); 1468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ok=checkFromUnicode( 1469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc, cnv, steps[i].utf8Name, 1470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (uint8_t *)result, resultLength, 1471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 1472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode); 1473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode) || !cc.finalFlush) { 1474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // reset if an error occurred or we did not flush 1475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // otherwise do nothing to make sure that flushing resets 1476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetToUnicode(utf8Cnv); 1477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_resetFromUnicode(cnv); 1478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // not a real loop, just a convenience for breaking out of the block 1483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ok && cc.finalFlush) { 1484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // test ucnv_fromUChars() 1485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memset(result, 0, sizeof(result)); 1486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 1488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLength=ucnv_fromUChars(cnv, 1489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result, LENGTHOF(result), 1490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.unicode, cc.unicodeLength, 1491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &errorCode); 1492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ok=checkFromUnicode( 1493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc, cnv, "fromUChars", 1494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (uint8_t *)result, resultLength, 1495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 1496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode); 1497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!ok) { 1498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // test preflighting 1502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // keep the correct result for simple checking 1503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 1504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLength=ucnv_fromUChars(cnv, 1505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 0, 1506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.unicode, cc.unicodeLength, 1507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &errorCode); 1508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(errorCode==U_STRING_NOT_TERMINATED_WARNING || errorCode==U_BUFFER_OVERFLOW_ERROR) { 1509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 1510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ok=checkFromUnicode( 1512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc, cnv, "preflight fromUChars", 1513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (uint8_t *)result, resultLength, 1514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 1515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode); 1516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_close(cnv); 1520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ok; 1521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool 1524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ConversionTest::checkFromUnicode(ConversionCase &cc, UConverter *cnv, const char *name, 1525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const uint8_t *result, int32_t resultLength, 1526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const int32_t *resultOffsets, 1527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode resultErrorCode) { 1528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar resultInvalidUChars[8]; 1529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int8_t resultInvalidLength; 1530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode; 1531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *msg; 1533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // reset the message; NULL will mean "ok" 1535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg=NULL; 1536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode=U_ZERO_ERROR; 1538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultInvalidLength=LENGTHOF(resultInvalidUChars); 1539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_getInvalidUChars(cnv, resultInvalidUChars, &resultInvalidLength, &errorCode); 1540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 1541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("fromUnicode[%d](%s cb=\"%s\" fb=%d flush=%d %s) ucnv_getInvalidUChars() failed - %s", 1542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, name, u_errorName(errorCode)); 1543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 1544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // check everything that might have gone wrong 1547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cc.bytesLength!=resultLength) { 1548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong result length"; 1549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(0!=memcmp(cc.bytes, result, cc.bytesLength)) { 1550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong result string"; 1551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(cc.offsets!=NULL && 0!=memcmp(cc.offsets, resultOffsets, cc.bytesLength*sizeof(*cc.offsets))) { 1552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong offsets"; 1553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(cc.outErrorCode!=resultErrorCode) { 1554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong error code"; 1555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(cc.invalidLength!=resultInvalidLength) { 1556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong length of last invalid input"; 1557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(0!=u_memcmp(cc.invalidUChars, resultInvalidUChars, cc.invalidLength)) { 1558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg="wrong last invalid input"; 1559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(msg==NULL) { 1562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 1563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char buffer[2000]; // one buffer for all strings 1565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *s, *unicodeString, *bytesString, *resultString, 1566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *offsetsString, *resultOffsetsString, 1567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *invalidCharsString, *resultInvalidUCharsString; 1568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unicodeString=s=buffer; 1570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printUnicode(cc.unicode, cc.unicodeLength, unicodeString); 1571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printBytes(cc.bytes, cc.bytesLength, bytesString=s); 1572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printBytes(result, resultLength, resultString=s); 1573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printOffsets(cc.offsets, cc.bytesLength, offsetsString=s); 1574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printOffsets(resultOffsets, resultLength, resultOffsetsString=s); 1575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printUnicode(cc.invalidUChars, cc.invalidLength, invalidCharsString=s); 1576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s=printUnicode(resultInvalidUChars, resultInvalidLength, resultInvalidUCharsString=s); 1577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((s-buffer)>(int32_t)sizeof(buffer)) { 1579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("fromUnicode[%d](%s cb=\"%s\" fb=%d flush=%d %s) fatal error: checkFromUnicode() test output buffer overflow writing %d chars\n", 1580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, name, (int)(s-buffer)); 1581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) exit(1); 1582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errln("fromUnicode[%d](%s cb=\"%s\" fb=%d flush=%d %s) failed: %s\n" 1585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " unicode <%s>[%d]\n" 1586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " expected <%s>[%d]\n" 1587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " result <%s>[%d]\n" 1588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " offsets <%s>\n" 1589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " result offsets <%s>\n" 1590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " error code expected %s got %s\n" 1591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) " invalidChars expected <%s> got <%s>\n", 1592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cc.caseNr, cc.charset, cc.cbopt, cc.fallbacks, cc.finalFlush, name, msg, 1593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unicodeString, cc.unicodeLength, 1594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bytesString, cc.bytesLength, 1595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultString, resultLength, 1596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) offsetsString, 1597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultOffsetsString, 1598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_errorName(cc.outErrorCode), u_errorName(resultErrorCode), 1599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) invalidCharsString, resultInvalidUCharsString); 1600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 1602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_LEGACY_CONVERSION */ 1606