1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/********************************************************************
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Copyright (c) 1997-2010, International Business Machines
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Corporation and others. All Rights Reserved.
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ********************************************************************
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * File UCNVSELTST.C
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Modification History:
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *        Name                     Description
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *     MOHAMED ELDAWY               Creation
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ********************************************************************
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* C API AND FUNCTIONALITY TEST FOR CONVERTER SELECTOR (ucnvsel.h)*/
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucnvseltst.h"
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h>
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ucnvsel.h"
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h"
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h"
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h"
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "propsvec.h"
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define FILENAME_BUFFER 1024
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define TDSRCPATH  ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestSelector(void);
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestUPropsVector(void);
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void addCnvSelTest(TestNode** root);  /* Declaration required to suppress compiler warnings. */
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void addCnvSelTest(TestNode** root)
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestSelector, "tsconv/ucnvseltst/TestSelector");
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    addTest(root, &TestUPropsVector, "tsconv/ucnvseltst/TestUPropsVector");
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **gAvailableNames = NULL;
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t gCountAvailable = 0;
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getAvailableNames() {
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int32_t i;
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (gAvailableNames != NULL) {
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return TRUE;
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  gCountAvailable = ucnv_countAvailable();
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (gCountAvailable == 0) {
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_data_err("No converters available.\n");
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return FALSE;
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  gAvailableNames = (const char **)uprv_malloc(gCountAvailable * sizeof(const char *));
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (gAvailableNames == NULL) {
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_err("unable to allocate memory for %ld available converter names\n",
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            (long)gCountAvailable);
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return FALSE;
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (i = 0; i < gCountAvailable; ++i) {
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    gAvailableNames[i] = ucnv_getAvailableName(i);
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return TRUE;
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)releaseAvailableNames() {
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  uprv_free((void *)gAvailableNames);
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  gAvailableNames = NULL;
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  gCountAvailable = 0;
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getEncodings(int32_t start, int32_t step, int32_t count, int32_t *pCount) {
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const char **names;
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int32_t i;
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  *pCount = 0;
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (count <= 0) {
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return NULL;
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  names = (const char **)uprv_malloc(count * sizeof(char *));
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (names == NULL) {
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_err("memory allocation error for %ld pointers\n", (long)count);
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return NULL;
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (step == 0 && count > 0) {
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    step = 1;
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (i = 0; i < count; ++i) {
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (0 <= start && start < gCountAvailable) {
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      names[i] = gAvailableNames[start];
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      start += step;
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      ++*pCount;
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return names;
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if 0
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ucnvsel_open() does not support "no encodings":
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Given 0 encodings it will open a selector for all available ones.
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getNoEncodings(int32_t *pCount) {
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  *pCount = 0;
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return NULL;
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getOneEncoding(int32_t *pCount) {
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return getEncodings(1, 0, 1, pCount);
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getFirstEvenEncodings(int32_t *pCount) {
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return getEncodings(0, 2, 25, pCount);
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getMiddleEncodings(int32_t *pCount) {
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return getEncodings(gCountAvailable - 12, 1, 22, pCount);
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getLastEncodings(int32_t *pCount) {
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return getEncodings(gCountAvailable - 1, -1, 25, pCount);
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getSomeEncodings(int32_t *pCount) {
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  /* 20 evenly distributed */
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return getEncodings(5, (gCountAvailable + 19)/ 20, 20, pCount);
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getEveryThirdEncoding(int32_t *pCount) {
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return getEncodings(2, 3, (gCountAvailable + 2 )/ 3, pCount);
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char **
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getAllEncodings(int32_t *pCount) {
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return getEncodings(0, 1, gCountAvailable, pCount);
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef const char **GetEncodingsFn(int32_t *);
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static GetEncodingsFn *const getEncodingsFns[] = {
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  getOneEncoding,
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  getFirstEvenEncodings,
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  getMiddleEncodings,
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  getLastEncodings,
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  getSomeEncodings,
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  getEveryThirdEncoding,
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  getAllEncodings
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static FILE *fopenOrError(const char *filename) {
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t needLen;
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    FILE *f;
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char fnbuf[FILENAME_BUFFER];
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const char* directory= ctest_dataSrcDir();
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    needLen = uprv_strlen(directory)+uprv_strlen(TDSRCPATH)+uprv_strlen(filename)+1;
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(needLen > FILENAME_BUFFER) {
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("FAIL: Could not load %s. Filename buffer overflow, needed %d but buffer is %d\n",
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                filename, needLen, FILENAME_BUFFER);
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return NULL;
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strcpy(fnbuf, directory);
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strcat(fnbuf, TDSRCPATH);
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strcat(fnbuf, filename);
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    f = fopen(fnbuf, "rb");
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(f == NULL) {
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_data_err("FAIL: Could not load %s [%s]\n", fnbuf, filename);
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return f;
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct TestText {
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  char *text, *textLimit;
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  char *limit;
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int32_t number;
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} TestText;
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)text_reset(TestText *tt) {
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  tt->limit = tt->text;
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  tt->number = 0;
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char *
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)text_nextString(TestText *tt, int32_t *pLength) {
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  char *s = tt->limit;
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (s == tt->textLimit) {
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* we already delivered the last string */
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return NULL;
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  } else if (s == tt->text) {
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* first string */
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ((tt->textLimit - tt->text) >= 3 &&
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s[0] == (char)0xef && s[1] == (char)0xbb && s[2] == (char)0xbf
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ) {
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      s += 3;  /* skip the UTF-8 signature byte sequence (U+FEFF) */
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  } else {
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* skip the string terminator */
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ++s;
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ++tt->number;
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  /* find the end of this string */
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  tt->limit = uprv_strchr(s, 0);
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  *pLength = (int32_t)(tt->limit - s);
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return s;
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)text_open(TestText *tt) {
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  FILE *f;
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  char *s;
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int32_t length;
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  uprv_memset(tt, 0, sizeof(TestText));
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  f = fopenOrError("ConverterSelectorTestUTF8.txt");
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(!f) {
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return FALSE;
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fseek(f, 0, SEEK_END);
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  length = (int32_t)ftell(f);
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fseek(f, 0, SEEK_SET);
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  tt->text = (char *)uprv_malloc(length + 1);
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (tt->text == NULL) {
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fclose(f);
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return FALSE;
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (length != fread(tt->text, 1, length, f)) {
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_err("error reading %ld bytes from test text file\n", (long)length);
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length = 0;
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(tt->text);
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fclose(f);
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  tt->textLimit = tt->text + length;
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  *tt->textLimit = 0;
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  /* replace all Unicode '#' (U+0023) with NUL */
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for(s = tt->text; (s = uprv_strchr(s, 0x23)) != NULL; *s++ = 0) {}
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  text_reset(tt);
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return TRUE;
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)text_close(TestText *tt) {
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  uprv_free(tt->text);
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t findIndex(const char* converterName) {
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int32_t i;
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (i = 0 ; i < gCountAvailable; i++) {
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(ucnv_compareNames(gAvailableNames[i], converterName) == 0) {
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return i;
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return -1;
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool *
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getResultsManually(const char** encodings, int32_t num_encodings,
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   const char *utf8, int32_t length,
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   const USet* excludedCodePoints, const UConverterUnicodeSet whichSet) {
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UBool* resultsManually;
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int32_t i;
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  resultsManually = (UBool*) uprv_malloc(gCountAvailable);
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  uprv_memset(resultsManually, 0, gCountAvailable);
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for(i = 0 ; i < num_encodings ; i++) {
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode status = U_ZERO_ERROR;
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* get unicode set for that converter */
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    USet* set;
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UConverter* test_converter;
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar32 cp;
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t encIndex, offset;
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    set = uset_openEmpty();
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    test_converter = ucnv_open(encodings[i], &status);
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ucnv_getUnicodeSet(test_converter, set,
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                       whichSet, &status);
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (excludedCodePoints != NULL) {
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      uset_addAll(set, excludedCodePoints);
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uset_freeze(set);
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    offset = 0;
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    cp = 0;
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    encIndex = findIndex(encodings[i]);
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * The following is almost, but not entirely, the same as
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * resultsManually[encIndex] =
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     *   (UBool)(uset_spanUTF8(set, utf8, length, USET_SPAN_SIMPLE) == length);
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * They might be different if the set contains strings,
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * or if the utf8 string contains an illegal sequence.
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     *
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * The UConverterSelector does not currently handle strings that can be
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * converted, and it treats an illegal sequence as convertible
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * while uset_spanUTF8() treats it like U+FFFD which may not be convertible.
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    resultsManually[encIndex] = TRUE;
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while(offset<length) {
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      U8_NEXT(utf8, offset, length, cp);
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if (cp >= 0 && !uset_contains(set, cp)) {
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        resultsManually[encIndex] = FALSE;
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uset_close(set);
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ucnv_close(test_converter);
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return resultsManually;
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* closes res but does not free resultsManually */
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void verifyResult(UEnumeration* res, const UBool *resultsManually) {
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UBool* resultsFromSystem = (UBool*) uprv_malloc(gCountAvailable * sizeof(UBool));
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  const char* name;
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UErrorCode status = U_ZERO_ERROR;
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int32_t i;
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  /* fill the bool for the selector results! */
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  uprv_memset(resultsFromSystem, 0, gCountAvailable);
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  while ((name = uenum_next(res,NULL, &status)) != NULL) {
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    resultsFromSystem[findIndex(name)] = TRUE;
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for(i = 0 ; i < gCountAvailable; i++) {
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(resultsManually[i] != resultsFromSystem[i]) {
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_err("failure in converter selector\n"
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              "converter %s had conflicting results -- manual: %d, system %d\n",
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              gAvailableNames[i], resultsManually[i], resultsFromSystem[i]);
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  uprv_free(resultsFromSystem);
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  uenum_close(res);
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UConverterSelector *
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)serializeAndUnserialize(UConverterSelector *sel, char **buffer, UErrorCode *status) {
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  char *new_buffer;
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int32_t ser_len, ser_len2;
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  /* preflight */
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  ser_len = ucnvsel_serialize(sel, NULL, 0, status);
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (*status != U_BUFFER_OVERFLOW_ERROR) {
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_err("ucnvsel_serialize(preflighting) failed: %s\n", u_errorName(*status));
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return sel;
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  new_buffer = (char *)uprv_malloc(ser_len);
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  *status = U_ZERO_ERROR;
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  ser_len2 = ucnvsel_serialize(sel, new_buffer, ser_len, status);
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (U_FAILURE(*status) || ser_len != ser_len2) {
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_err("ucnvsel_serialize() failed: %s\n", u_errorName(*status));
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(new_buffer);
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return sel;
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  ucnvsel_close(sel);
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  uprv_free(*buffer);
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  *buffer = new_buffer;
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  sel = ucnvsel_openFromSerialized(new_buffer, ser_len, status);
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (U_FAILURE(*status)) {
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_err("ucnvsel_openFromSerialized() failed: %s\n", u_errorName(*status));
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return NULL;
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return sel;
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestSelector()
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  TestText text;
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  USet* excluded_sets[3] = { NULL };
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  int32_t i, testCaseIdx;
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (!getAvailableNames()) {
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return;
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (!text_open(&text)) {
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    releaseAvailableNames();;
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  excluded_sets[0] = uset_openEmpty();
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for(i = 1 ; i < 3 ; i++) {
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    excluded_sets[i] = uset_open(i*30, i*30+500);
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for(testCaseIdx = 0; testCaseIdx < LENGTHOF(getEncodingsFns); testCaseIdx++)
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t excluded_set_id;
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t num_encodings;
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const char **encodings = getEncodingsFns[testCaseIdx](&num_encodings);
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (getTestOption(QUICK_OPTION) && num_encodings > 25) {
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      uprv_free((void *)encodings);
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      continue;
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * for(excluded_set_id = 0 ; excluded_set_id < 3 ; excluded_set_id++)
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     *
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * This loop was replaced by the following statement because
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * the loop made the test run longer without adding to the code coverage.
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * The handling of the exclusion set is independent of the
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * set of encodings, so there is no need to test every combination.
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    excluded_set_id = testCaseIdx % LENGTHOF(excluded_sets);
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      UConverterSelector *sel_rt, *sel_fb;
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      char *buffer_fb = NULL;
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      UErrorCode status = U_ZERO_ERROR;
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      sel_rt = ucnvsel_open(encodings, num_encodings,
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            excluded_sets[excluded_set_id],
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            UCNV_ROUNDTRIP_SET, &status);
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if (num_encodings == gCountAvailable) {
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* test the special "all converters" parameter values */
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sel_fb = ucnvsel_open(NULL, 0,
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              excluded_sets[excluded_set_id],
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              UCNV_ROUNDTRIP_AND_FALLBACK_SET, &status);
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      } else if (uset_isEmpty(excluded_sets[excluded_set_id])) {
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* test that a NULL set gives the same results as an empty set */
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sel_fb = ucnvsel_open(encodings, num_encodings,
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              NULL,
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              UCNV_ROUNDTRIP_AND_FALLBACK_SET, &status);
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      } else {
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sel_fb = ucnvsel_open(encodings, num_encodings,
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              excluded_sets[excluded_set_id],
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              UCNV_ROUNDTRIP_AND_FALLBACK_SET, &status);
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if (U_FAILURE(status)) {
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("ucnv_sel_open(encodings %ld) failed - %s\n", testCaseIdx, u_errorName(status));
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ucnvsel_close(sel_rt);
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free((void *)encodings);
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        continue;
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      text_reset(&text);
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      for (;;) {
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UBool *manual_rt, *manual_fb;
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        static UChar utf16[10000];
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        char *s;
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t length8, length16;
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s = text_nextString(&text, &length8);
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (s == NULL || (getTestOption(QUICK_OPTION) && text.number > 3)) {
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          break;
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        manual_rt = getResultsManually(encodings, num_encodings,
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                       s, length8,
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                       excluded_sets[excluded_set_id],
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                       UCNV_ROUNDTRIP_SET);
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        manual_fb = getResultsManually(encodings, num_encodings,
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                       s, length8,
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                       excluded_sets[excluded_set_id],
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                       UCNV_ROUNDTRIP_AND_FALLBACK_SET);
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* UTF-8 with length */
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_ZERO_ERROR;
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        verifyResult(ucnvsel_selectForUTF8(sel_rt, s, length8, &status), manual_rt);
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        verifyResult(ucnvsel_selectForUTF8(sel_fb, s, length8, &status), manual_fb);
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* UTF-8 NUL-terminated */
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        verifyResult(ucnvsel_selectForUTF8(sel_rt, s, -1, &status), manual_rt);
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        verifyResult(ucnvsel_selectForUTF8(sel_fb, s, -1, &status), manual_fb);
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        u_strFromUTF8(utf16, LENGTHOF(utf16), &length16, s, length8, &status);
473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_FAILURE(status)) {
474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          log_err("error converting the test text (string %ld) to UTF-16 - %s\n",
475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  (long)text.number, u_errorName(status));
476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          if (text.number == 0) {
478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            sel_fb = serializeAndUnserialize(sel_fb, &buffer_fb, &status);
479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          }
480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          if (U_SUCCESS(status)) {
481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* UTF-16 with length */
482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            verifyResult(ucnvsel_selectForString(sel_rt, utf16, length16, &status), manual_rt);
483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            verifyResult(ucnvsel_selectForString(sel_fb, utf16, length16, &status), manual_fb);
484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* UTF-16 NUL-terminated */
485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            verifyResult(ucnvsel_selectForString(sel_rt, utf16, -1, &status), manual_rt);
486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            verifyResult(ucnvsel_selectForString(sel_fb, utf16, -1, &status), manual_fb);
487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          }
488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(manual_rt);
491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(manual_fb);
492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      ucnvsel_close(sel_rt);
494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      ucnvsel_close(sel_fb);
495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      uprv_free(buffer_fb);
496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free((void *)encodings);
498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  releaseAvailableNames();
501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  text_close(&text);
502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for(i = 0 ; i < 3 ; i++) {
503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uset_close(excluded_sets[i]);
504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Improve code coverage of UPropsVectors */
508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void TestUPropsVector() {
509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t value;
510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode = U_ILLEGAL_ARGUMENT_ERROR;
511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UPropsVectors *pv = upvec_open(100, &errorCode);
512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (pv != NULL) {
513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("Should have returned NULL if UErrorCode is an error.");
514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode = U_ZERO_ERROR;
517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    pv = upvec_open(-1, &errorCode);
518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (pv != NULL || U_SUCCESS(errorCode)) {
519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("Should have returned NULL if column is less than 0.\n");
520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errorCode = U_ZERO_ERROR;
523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    pv = upvec_open(100, &errorCode);
524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (pv == NULL || U_FAILURE(errorCode)) {
525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("Unable to open UPropsVectors.\n");
526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (upvec_getValue(pv, 0, 1) != 0) {
530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("upvec_getValue should return 0.\n");
531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (upvec_getRow(pv, 0, NULL, NULL) == NULL) {
533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("upvec_getRow should not return NULL.\n");
534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (upvec_getArray(pv, NULL, NULL) != NULL) {
536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("upvec_getArray should return NULL.\n");
537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    upvec_close(pv);
540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
541