Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Unified Diff: icu46/source/test/cintltst/ucnvseltst.c

Issue 5516007: Check in the pristine copy of ICU 4.6... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/
Patch Set: Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « icu46/source/test/cintltst/ucnvseltst.h ('k') | icu46/source/test/cintltst/ucsdetst.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: icu46/source/test/cintltst/ucnvseltst.c
===================================================================
--- icu46/source/test/cintltst/ucnvseltst.c (revision 0)
+++ icu46/source/test/cintltst/ucnvseltst.c (revision 0)
@@ -0,0 +1,540 @@
+/********************************************************************
+ * Copyright (c) 1997-2010, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ ********************************************************************
+ *
+ * File UCNVSELTST.C
+ *
+ * Modification History:
+ * Name Description
+ * MOHAMED ELDAWY Creation
+ ********************************************************************
+ */
+
+/* C API AND FUNCTIONALITY TEST FOR CONVERTER SELECTOR (ucnvsel.h)*/
+
+#include "ucnvseltst.h"
+
+#include <stdio.h>
+
+#include "unicode/utypes.h"
+#include "unicode/ucnvsel.h"
+#include "unicode/ustring.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "propsvec.h"
+
+#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
+
+#define FILENAME_BUFFER 1024
+
+#define TDSRCPATH ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING
+
+static void TestSelector(void);
+static void TestUPropsVector(void);
+void addCnvSelTest(TestNode** root); /* Declaration required to suppress compiler warnings. */
+
+void addCnvSelTest(TestNode** root)
+{
+ addTest(root, &TestSelector, "tsconv/ucnvseltst/TestSelector");
+ addTest(root, &TestUPropsVector, "tsconv/ucnvseltst/TestUPropsVector");
+}
+
+static const char **gAvailableNames = NULL;
+static int32_t gCountAvailable = 0;
+
+static UBool
+getAvailableNames() {
+ int32_t i;
+ if (gAvailableNames != NULL) {
+ return TRUE;
+ }
+ gCountAvailable = ucnv_countAvailable();
+ if (gCountAvailable == 0) {
+ log_data_err("No converters available.\n");
+ return FALSE;
+ }
+ gAvailableNames = (const char **)uprv_malloc(gCountAvailable * sizeof(const char *));
+ if (gAvailableNames == NULL) {
+ log_err("unable to allocate memory for %ld available converter names\n",
+ (long)gCountAvailable);
+ return FALSE;
+ }
+ for (i = 0; i < gCountAvailable; ++i) {
+ gAvailableNames[i] = ucnv_getAvailableName(i);
+ }
+ return TRUE;
+}
+
+static void
+releaseAvailableNames() {
+ uprv_free((void *)gAvailableNames);
+ gAvailableNames = NULL;
+ gCountAvailable = 0;
+}
+
+static const char **
+getEncodings(int32_t start, int32_t step, int32_t count, int32_t *pCount) {
+ const char **names;
+ int32_t i;
+
+ *pCount = 0;
+ if (count <= 0) {
+ return NULL;
+ }
+ names = (const char **)uprv_malloc(count * sizeof(char *));
+ if (names == NULL) {
+ log_err("memory allocation error for %ld pointers\n", (long)count);
+ return NULL;
+ }
+ if (step == 0 && count > 0) {
+ step = 1;
+ }
+ for (i = 0; i < count; ++i) {
+ if (0 <= start && start < gCountAvailable) {
+ names[i] = gAvailableNames[start];
+ start += step;
+ ++*pCount;
+ }
+ }
+ return names;
+}
+
+#if 0
+/*
+ * ucnvsel_open() does not support "no encodings":
+ * Given 0 encodings it will open a selector for all available ones.
+ */
+static const char **
+getNoEncodings(int32_t *pCount) {
+ *pCount = 0;
+ return NULL;
+}
+#endif
+
+static const char **
+getOneEncoding(int32_t *pCount) {
+ return getEncodings(1, 0, 1, pCount);
+}
+
+static const char **
+getFirstEvenEncodings(int32_t *pCount) {
+ return getEncodings(0, 2, 25, pCount);
+}
+
+static const char **
+getMiddleEncodings(int32_t *pCount) {
+ return getEncodings(gCountAvailable - 12, 1, 22, pCount);
+}
+
+static const char **
+getLastEncodings(int32_t *pCount) {
+ return getEncodings(gCountAvailable - 1, -1, 25, pCount);
+}
+
+static const char **
+getSomeEncodings(int32_t *pCount) {
+ /* 20 evenly distributed */
+ return getEncodings(5, (gCountAvailable + 19)/ 20, 20, pCount);
+}
+
+static const char **
+getEveryThirdEncoding(int32_t *pCount) {
+ return getEncodings(2, 3, (gCountAvailable + 2 )/ 3, pCount);
+}
+
+static const char **
+getAllEncodings(int32_t *pCount) {
+ return getEncodings(0, 1, gCountAvailable, pCount);
+}
+
+typedef const char **GetEncodingsFn(int32_t *);
+
+static GetEncodingsFn *const getEncodingsFns[] = {
+ getOneEncoding,
+ getFirstEvenEncodings,
+ getMiddleEncodings,
+ getLastEncodings,
+ getSomeEncodings,
+ getEveryThirdEncoding,
+ getAllEncodings
+};
+
+static FILE *fopenOrError(const char *filename) {
+ int32_t needLen;
+ FILE *f;
+ char fnbuf[FILENAME_BUFFER];
+ const char* directory= ctest_dataSrcDir();
+ needLen = uprv_strlen(directory)+uprv_strlen(TDSRCPATH)+uprv_strlen(filename)+1;
+ if(needLen > FILENAME_BUFFER) {
+ log_err("FAIL: Could not load %s. Filename buffer overflow, needed %d but buffer is %d\n",
+ filename, needLen, FILENAME_BUFFER);
+ return NULL;
+ }
+
+ strcpy(fnbuf, directory);
+ strcat(fnbuf, TDSRCPATH);
+ strcat(fnbuf, filename);
+
+ f = fopen(fnbuf, "rb");
+
+ if(f == NULL) {
+ log_data_err("FAIL: Could not load %s [%s]\n", fnbuf, filename);
+ }
+ return f;
+}
+
+typedef struct TestText {
+ char *text, *textLimit;
+ char *limit;
+ int32_t number;
+} TestText;
+
+static void
+text_reset(TestText *tt) {
+ tt->limit = tt->text;
+ tt->number = 0;
+}
+
+static char *
+text_nextString(TestText *tt, int32_t *pLength) {
+ char *s = tt->limit;
+ if (s == tt->textLimit) {
+ /* we already delivered the last string */
+ return NULL;
+ } else if (s == tt->text) {
+ /* first string */
+ if ((tt->textLimit - tt->text) >= 3 &&
+ s[0] == (char)0xef && s[1] == (char)0xbb && s[2] == (char)0xbf
+ ) {
+ s += 3; /* skip the UTF-8 signature byte sequence (U+FEFF) */
+ }
+ } else {
+ /* skip the string terminator */
+ ++s;
+ ++tt->number;
+ }
+
+ /* find the end of this string */
+ tt->limit = uprv_strchr(s, 0);
+ *pLength = (int32_t)(tt->limit - s);
+ return s;
+}
+
+static UBool
+text_open(TestText *tt) {
+ FILE *f;
+ char *s;
+ int32_t length;
+ uprv_memset(tt, 0, sizeof(TestText));
+ f = fopenOrError("ConverterSelectorTestUTF8.txt");
+ if(!f) {
+ return FALSE;
+ }
+ fseek(f, 0, SEEK_END);
+ length = (int32_t)ftell(f);
+ fseek(f, 0, SEEK_SET);
+ tt->text = (char *)uprv_malloc(length + 1);
+ if (tt->text == NULL) {
+ fclose(f);
+ return FALSE;
+ }
+ if (length != fread(tt->text, 1, length, f)) {
+ log_err("error reading %ld bytes from test text file\n", (long)length);
+ length = 0;
+ uprv_free(tt->text);
+ }
+ fclose(f);
+ tt->textLimit = tt->text + length;
+ *tt->textLimit = 0;
+ /* replace all Unicode '#' (U+0023) with NUL */
+ for(s = tt->text; (s = uprv_strchr(s, 0x23)) != NULL; *s++ = 0) {}
+ text_reset(tt);
+ return TRUE;
+}
+
+static void
+text_close(TestText *tt) {
+ uprv_free(tt->text);
+}
+
+static int32_t findIndex(const char* converterName) {
+ int32_t i;
+ for (i = 0 ; i < gCountAvailable; i++) {
+ if(ucnv_compareNames(gAvailableNames[i], converterName) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static UBool *
+getResultsManually(const char** encodings, int32_t num_encodings,
+ const char *utf8, int32_t length,
+ const USet* excludedCodePoints, const UConverterUnicodeSet whichSet) {
+ UBool* resultsManually;
+ int32_t i;
+
+ resultsManually = (UBool*) uprv_malloc(gCountAvailable);
+ uprv_memset(resultsManually, 0, gCountAvailable);
+
+ for(i = 0 ; i < num_encodings ; i++) {
+ UErrorCode status = U_ZERO_ERROR;
+ /* get unicode set for that converter */
+ USet* set;
+ UConverter* test_converter;
+ UChar32 cp;
+ int32_t encIndex, offset;
+
+ set = uset_openEmpty();
+ test_converter = ucnv_open(encodings[i], &status);
+ ucnv_getUnicodeSet(test_converter, set,
+ whichSet, &status);
+ if (excludedCodePoints != NULL) {
+ uset_addAll(set, excludedCodePoints);
+ }
+ uset_freeze(set);
+ offset = 0;
+ cp = 0;
+
+ encIndex = findIndex(encodings[i]);
+ /*
+ * The following is almost, but not entirely, the same as
+ * resultsManually[encIndex] =
+ * (UBool)(uset_spanUTF8(set, utf8, length, USET_SPAN_SIMPLE) == length);
+ * They might be different if the set contains strings,
+ * or if the utf8 string contains an illegal sequence.
+ *
+ * The UConverterSelector does not currently handle strings that can be
+ * converted, and it treats an illegal sequence as convertible
+ * while uset_spanUTF8() treats it like U+FFFD which may not be convertible.
+ */
+ resultsManually[encIndex] = TRUE;
+ while(offset<length) {
+ U8_NEXT(utf8, offset, length, cp);
+ if (cp >= 0 && !uset_contains(set, cp)) {
+ resultsManually[encIndex] = FALSE;
+ break;
+ }
+ }
+ uset_close(set);
+ ucnv_close(test_converter);
+ }
+ return resultsManually;
+}
+
+/* closes res but does not free resultsManually */
+static void verifyResult(UEnumeration* res, const UBool *resultsManually) {
+ UBool* resultsFromSystem = (UBool*) uprv_malloc(gCountAvailable * sizeof(UBool));
+ const char* name;
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t i;
+
+ /* fill the bool for the selector results! */
+ uprv_memset(resultsFromSystem, 0, gCountAvailable);
+ while ((name = uenum_next(res,NULL, &status)) != NULL) {
+ resultsFromSystem[findIndex(name)] = TRUE;
+ }
+ for(i = 0 ; i < gCountAvailable; i++) {
+ if(resultsManually[i] != resultsFromSystem[i]) {
+ log_err("failure in converter selector\n"
+ "converter %s had conflicting results -- manual: %d, system %d\n",
+ gAvailableNames[i], resultsManually[i], resultsFromSystem[i]);
+ }
+ }
+ uprv_free(resultsFromSystem);
+ uenum_close(res);
+}
+
+static UConverterSelector *
+serializeAndUnserialize(UConverterSelector *sel, char **buffer, UErrorCode *status) {
+ char *new_buffer;
+ int32_t ser_len, ser_len2;
+ /* preflight */
+ ser_len = ucnvsel_serialize(sel, NULL, 0, status);
+ if (*status != U_BUFFER_OVERFLOW_ERROR) {
+ log_err("ucnvsel_serialize(preflighting) failed: %s\n", u_errorName(*status));
+ return sel;
+ }
+ new_buffer = (char *)uprv_malloc(ser_len);
+ *status = U_ZERO_ERROR;
+ ser_len2 = ucnvsel_serialize(sel, new_buffer, ser_len, status);
+ if (U_FAILURE(*status) || ser_len != ser_len2) {
+ log_err("ucnvsel_serialize() failed: %s\n", u_errorName(*status));
+ uprv_free(new_buffer);
+ return sel;
+ }
+ ucnvsel_close(sel);
+ uprv_free(*buffer);
+ *buffer = new_buffer;
+ sel = ucnvsel_openFromSerialized(new_buffer, ser_len, status);
+ if (U_FAILURE(*status)) {
+ log_err("ucnvsel_openFromSerialized() failed: %s\n", u_errorName(*status));
+ return NULL;
+ }
+ return sel;
+}
+
+static void TestSelector()
+{
+ TestText text;
+ USet* excluded_sets[3] = { NULL };
+ int32_t i, testCaseIdx;
+
+ if (!getAvailableNames()) {
+ return;
+ }
+ if (!text_open(&text)) {
+ releaseAvailableNames();;
+ }
+
+ excluded_sets[0] = uset_openEmpty();
+ for(i = 1 ; i < 3 ; i++) {
+ excluded_sets[i] = uset_open(i*30, i*30+500);
+ }
+
+ for(testCaseIdx = 0; testCaseIdx < LENGTHOF(getEncodingsFns); testCaseIdx++)
+ {
+ int32_t excluded_set_id;
+ int32_t num_encodings;
+ const char **encodings = getEncodingsFns[testCaseIdx](&num_encodings);
+ if (getTestOption(QUICK_OPTION) && num_encodings > 25) {
+ uprv_free((void *)encodings);
+ continue;
+ }
+
+ /*
+ * for(excluded_set_id = 0 ; excluded_set_id < 3 ; excluded_set_id++)
+ *
+ * This loop was replaced by the following statement because
+ * the loop made the test run longer without adding to the code coverage.
+ * The handling of the exclusion set is independent of the
+ * set of encodings, so there is no need to test every combination.
+ */
+ excluded_set_id = testCaseIdx % LENGTHOF(excluded_sets);
+ {
+ UConverterSelector *sel_rt, *sel_fb;
+ char *buffer_fb = NULL;
+ UErrorCode status = U_ZERO_ERROR;
+ sel_rt = ucnvsel_open(encodings, num_encodings,
+ excluded_sets[excluded_set_id],
+ UCNV_ROUNDTRIP_SET, &status);
+ if (num_encodings == gCountAvailable) {
+ /* test the special "all converters" parameter values */
+ sel_fb = ucnvsel_open(NULL, 0,
+ excluded_sets[excluded_set_id],
+ UCNV_ROUNDTRIP_AND_FALLBACK_SET, &status);
+ } else if (uset_isEmpty(excluded_sets[excluded_set_id])) {
+ /* test that a NULL set gives the same results as an empty set */
+ sel_fb = ucnvsel_open(encodings, num_encodings,
+ NULL,
+ UCNV_ROUNDTRIP_AND_FALLBACK_SET, &status);
+ } else {
+ sel_fb = ucnvsel_open(encodings, num_encodings,
+ excluded_sets[excluded_set_id],
+ UCNV_ROUNDTRIP_AND_FALLBACK_SET, &status);
+ }
+ if (U_FAILURE(status)) {
+ log_err("ucnv_sel_open(encodings %ld) failed - %s\n", testCaseIdx, u_errorName(status));
+ ucnvsel_close(sel_rt);
+ uprv_free((void *)encodings);
+ continue;
+ }
+
+ text_reset(&text);
+ for (;;) {
+ UBool *manual_rt, *manual_fb;
+ static UChar utf16[10000];
+ char *s;
+ int32_t length8, length16;
+
+ s = text_nextString(&text, &length8);
+ if (s == NULL || (getTestOption(QUICK_OPTION) && text.number > 3)) {
+ break;
+ }
+
+ manual_rt = getResultsManually(encodings, num_encodings,
+ s, length8,
+ excluded_sets[excluded_set_id],
+ UCNV_ROUNDTRIP_SET);
+ manual_fb = getResultsManually(encodings, num_encodings,
+ s, length8,
+ excluded_sets[excluded_set_id],
+ UCNV_ROUNDTRIP_AND_FALLBACK_SET);
+ /* UTF-8 with length */
+ status = U_ZERO_ERROR;
+ verifyResult(ucnvsel_selectForUTF8(sel_rt, s, length8, &status), manual_rt);
+ verifyResult(ucnvsel_selectForUTF8(sel_fb, s, length8, &status), manual_fb);
+ /* UTF-8 NUL-terminated */
+ verifyResult(ucnvsel_selectForUTF8(sel_rt, s, -1, &status), manual_rt);
+ verifyResult(ucnvsel_selectForUTF8(sel_fb, s, -1, &status), manual_fb);
+
+ u_strFromUTF8(utf16, LENGTHOF(utf16), &length16, s, length8, &status);
+ if (U_FAILURE(status)) {
+ log_err("error converting the test text (string %ld) to UTF-16 - %s\n",
+ (long)text.number, u_errorName(status));
+ } else {
+ if (text.number == 0) {
+ sel_fb = serializeAndUnserialize(sel_fb, &buffer_fb, &status);
+ }
+ if (U_SUCCESS(status)) {
+ /* UTF-16 with length */
+ verifyResult(ucnvsel_selectForString(sel_rt, utf16, length16, &status), manual_rt);
+ verifyResult(ucnvsel_selectForString(sel_fb, utf16, length16, &status), manual_fb);
+ /* UTF-16 NUL-terminated */
+ verifyResult(ucnvsel_selectForString(sel_rt, utf16, -1, &status), manual_rt);
+ verifyResult(ucnvsel_selectForString(sel_fb, utf16, -1, &status), manual_fb);
+ }
+ }
+
+ uprv_free(manual_rt);
+ uprv_free(manual_fb);
+ }
+ ucnvsel_close(sel_rt);
+ ucnvsel_close(sel_fb);
+ uprv_free(buffer_fb);
+ }
+ uprv_free((void *)encodings);
+ }
+
+ releaseAvailableNames();
+ text_close(&text);
+ for(i = 0 ; i < 3 ; i++) {
+ uset_close(excluded_sets[i]);
+ }
+}
+
+/* Improve code coverage of UPropsVectors */
+static void TestUPropsVector() {
+ uint32_t value;
+ UErrorCode errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ UPropsVectors *pv = upvec_open(100, &errorCode);
+ if (pv != NULL) {
+ log_err("Should have returned NULL if UErrorCode is an error.");
+ return;
+ }
+ errorCode = U_ZERO_ERROR;
+ pv = upvec_open(-1, &errorCode);
+ if (pv != NULL || U_SUCCESS(errorCode)) {
+ log_err("Should have returned NULL if column is less than 0.\n");
+ return;
+ }
+ errorCode = U_ZERO_ERROR;
+ pv = upvec_open(100, &errorCode);
+ if (pv == NULL || U_FAILURE(errorCode)) {
+ log_err("Unable to open UPropsVectors.\n");
+ return;
+ }
+
+ if (upvec_getValue(pv, 0, 1) != 0) {
+ log_err("upvec_getValue should return 0.\n");
+ }
+ if (upvec_getRow(pv, 0, NULL, NULL) == NULL) {
+ log_err("upvec_getRow should not return NULL.\n");
+ }
+ if (upvec_getArray(pv, NULL, NULL) != NULL) {
+ log_err("upvec_getArray should return NULL.\n");
+ }
+
+ upvec_close(pv);
+}
Property changes on: icu46/source/test/cintltst/ucnvseltst.c
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « icu46/source/test/cintltst/ucnvseltst.h ('k') | icu46/source/test/cintltst/ucsdetst.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698