1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *   Copyright (C) 2005-2009, International Business Machines
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *   Corporation and others.  All Rights Reserved.
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *   created on: 2005jun15
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *   created by: Raymond Yang
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_IDNA
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdlib.h>
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h>
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucnv.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h"
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uidna.h"
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "idnaconf.h"
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_TAG[] = {0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0}; // =====
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_NAMEZONE[] = {0x6E, 0x61, 0x6D, 0x65, 0x7A, 0x6F, 0x6E, 0x65, 0}; // namezone
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_NAMEBASE[] = {0x6E, 0x61, 0x6D, 0x65, 0x62, 0x61, 0x73, 0x65, 0}; // namebase
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_NAMEUTF8[] = {0x6E, 0x61, 0x6D, 0x65, 0x75, 0x74, 0x66, 0x38, 0}; // nameutf8
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_TYPE[] = {0x74, 0x79, 0x70, 0x65, 0}; // type
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_TOASCII[]  =  {0x74, 0x6F, 0x61, 0x73, 0x63, 0x69, 0x69, 0};       // toascii
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_TOUNICODE[] = {0x74, 0x6F, 0x75, 0x6E, 0x69, 0x63, 0x6F, 0x64, 0x65, 0}; // tounicode
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_PASSFAIL[] = {0x70, 0x61, 0x73, 0x73, 0x66, 0x61, 0x69, 0x6C, 0}; // passfail
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_PASS[] = {0x70, 0x61, 0x73, 0x73, 0}; // pass
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_FAIL[] = {0x66, 0x61, 0x69, 0x6C, 0}; // fail
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_DESC[] = {0x64, 0x65, 0x73, 0x63, 0}; // desc
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar C_USESTD3ASCIIRULES[] = {0x55, 0x73, 0x65, 0x53, 0x54, 0x44,
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru       0x33, 0x41, 0x53, 0x43, 0x49, 0x49, 0x52, 0x75, 0x6C, 0x65, 0x73, 0}; // UseSTD3ASCIIRules
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruIdnaConfTest::IdnaConfTest(){
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    base = NULL;
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = 0;
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    curOffset = 0;
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    type = option = passfail = -1;
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    namebase.setToBogus();
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    namezone.setToBogus();
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruIdnaConfTest::~IdnaConfTest(){
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete [] base;
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_IDNA
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* this function is modified from RBBITest::ReadAndConvertFile()
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool IdnaConfTest::ReadAndConvertFile(){
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char * source = NULL;
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    size_t source_len;
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // read the test data file to memory
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    FILE* f    = NULL;
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode  status  = U_ZERO_ERROR;
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *path = IntlTest::getSourceTestData(status);
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        errln("%s", u_errorName(status));
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return FALSE;
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char* name = "idna_conf.txt";     // test data file
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int t = strlen(path) + strlen(name) + 1;
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char* absolute_name = new char[t];
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    strcpy(absolute_name, path);
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    strcat(absolute_name, name);
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    f = fopen(absolute_name, "rb");
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete [] absolute_name;
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (f == NULL){
8385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        dataerrln("fopen error on %s", name);
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return FALSE;
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fseek( f, 0, SEEK_END);
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ((source_len = ftell(f)) <= 0){
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        errln("Error reading test data file.");
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fclose(f);
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return FALSE;
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    source = new char[source_len];
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fseek(f, 0, SEEK_SET);
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fread(source, 1, source_len, f) != source_len) {
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        errln("Error reading test data file.");
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete [] source;
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fclose(f);
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return FALSE;
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fclose(f);
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // convert the UTF-8 encoded stream to UTF-16 stream
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UConverter* conv = ucnv_open("utf-8", &status);
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int dest_len = ucnv_toUChars(conv,
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                NULL,           //  dest,
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                0,              //  destCapacity,
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                source,
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                source_len,
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                &status);
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (status == U_BUFFER_OVERFLOW_ERROR) {
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Buffer Overflow is expected from the preflight operation.
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_ZERO_ERROR;
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar * dest = NULL;
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dest = new UChar[ dest_len + 1];
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucnv_toUChars(conv, dest, dest_len + 1, source, source_len, &status);
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Do not know the "if possible" behavior of ucnv_toUChars()
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Do it by ourself.
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dest[dest_len] = 0;
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = dest_len;
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        base = dest;
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete [] source;
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucnv_close(conv);
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return TRUE;    // The buffer will owned by caller.
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    errln("UConverter error: %s", u_errorName(status));
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete [] source;
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ucnv_close(conv);
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint IdnaConfTest::isNewlineMark(){
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar LF        = 0x0a;
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar CR        = 0x0d;
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar c = base[curOffset];
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // CR LF
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ( c == CR && curOffset + 1 < len && base[curOffset + 1] == LF){
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 2;
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // CR or LF
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ( c == CR || c == LF) {
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 1;
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 0;
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Read a logical line.
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * All lines ending in a backslash (\) and immediately followed by a newline
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * character are joined with the next line in the source file forming logical
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * lines from the physical lines.
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool IdnaConfTest::ReadOneLine(UnicodeString& buf){
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ( !(curOffset < len) ) return FALSE; // stream end
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const UChar BACKSLASH = 0x5c;
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    buf.remove();
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int t = 0;
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (curOffset < len){
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if ((t = isNewlineMark())) {  // end of line
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            curOffset += t;
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar c = base[curOffset];
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (c == BACKSLASH && curOffset < len -1){  // escaped new line mark
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if ((t = isNewlineMark())){
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                curOffset += 1 + t;  // BACKSLAH and NewlineMark
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                continue;
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        };
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        buf.append(c);
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        curOffset++;
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return TRUE;
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//===============================================================
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Explain <xxxxx> tag to a native value
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Since <xxxxx> is always larger than the native value,
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the operation will replace the tag directly in the buffer,
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and, of course, will shift tail elements.
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid IdnaConfTest::ExplainCodePointTag(UnicodeString& buf){
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    buf.append((UChar)0);    // add a terminal NULL
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar* bufBase = buf.getBuffer(buf.length());
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar* p = bufBase;
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (*p != 0){
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if ( *p != 0x3C){    // <
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *bufBase++ = *p++;
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            p++;    // skip <
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UChar32 cp = 0;
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            for ( ;*p != 0x3E; p++){   // >
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (0x30 <= *p && *p <= 0x39){        // 0-9
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    cp = (cp * 16) + (*p - 0x30);
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else if (0x61 <= *p && *p <= 0x66){ // a-f
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    cp = (cp * 16) + (*p - 0x61) + 10;
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else if (0x41 <= *p && *p <= 0x46) {// A-F
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    cp = (cp * 16) + (*p - 0x41) + 10;
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // no else. hope everything is good.
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            p++;    // skip >
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_IS_BMP(cp)){
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *bufBase++ = cp;
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *bufBase++ = U16_LEAD(cp);
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *bufBase++ = U16_TRAIL(cp);
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *bufBase = 0;  // close our buffer
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    buf.releaseBuffer();
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid IdnaConfTest::Call(){
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (type == -1 || option == -1 || passfail == -1 || namebase.isBogus() || namezone.isBogus()){
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        errln("Incomplete record");
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar result[200] = {0,};   // simple life
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const UChar *p = namebase.getTerminatedBuffer();
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const int p_len = namebase.length();
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (type == 0 && option == 0){
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            uidna_IDNToASCII(p, p_len, result, 200, UIDNA_USE_STD3_RULES, NULL, &status);
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if (type == 0 && option == 1){
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            uidna_IDNToASCII(p, p_len, result, 200, UIDNA_ALLOW_UNASSIGNED, NULL, &status);
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if (type == 1 && option == 0){
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            uidna_IDNToUnicode(p, p_len, result, 200, UIDNA_USE_STD3_RULES, NULL, &status);
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if (type == 1 && option == 1){
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            uidna_IDNToUnicode(p, p_len, result, 200, UIDNA_ALLOW_UNASSIGNED, NULL, &status);
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (passfail == 0){
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(status)){
24485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                id.append(" should pass, but failed. - ");
24585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                id.append(u_errorName(status));
24685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                errcheckln(status, id);
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else{
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (namezone.compare(result, -1) == 0){
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    // expected
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    logln(UnicodeString("namebase: ") + prettify(namebase) + UnicodeString(" result: ") + prettify(result));
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else {
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    id.append(" no error, but result is not as expected.");
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    errln(id);
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if (passfail == 1){
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(status)){
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // expected
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // TODO: Uncomment this when U_IDNA_ZERO_LENGTH_LABEL_ERROR is added to u_errorName
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                //logln("Got the expected error: " + UnicodeString(u_errorName(status)));
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else{
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (namebase.compare(result, -1) == 0){
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    // garbage in -> garbage out
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    logln(UnicodeString("ICU will not recognize malformed ACE-Prefixes or incorrect ACE-Prefixes. ") + UnicodeString("namebase: ") + prettify(namebase) + UnicodeString(" result: ") + prettify(result));
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else {
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    id.append(" should fail, but not failed. ");
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    id.append(u_errorName(status));
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    errln(id);
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    type = option = passfail = -1;
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    namebase.setToBogus();
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    namezone.setToBogus();
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    id.remove();
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return;
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid IdnaConfTest::Test(void){
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!ReadAndConvertFile())return;
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString s;
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString key;
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString value;
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // skip everything before the first "=====" and "=====" itself
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    do {
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (!ReadOneLine(s)) {
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            errln("End of file prematurely found");
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (s.compare(C_TAG, -1) != 0);   //"====="
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(ReadOneLine(s)){
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        s.trim();
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        key.remove();
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        value.remove();
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (s.compare(C_TAG, -1) == 0){   //"====="
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            Call();
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru       } else {
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // explain      key:value
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int p = s.indexOf((UChar)0x3A);    // :
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            key.setTo(s,0,p).trim();
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            value.setTo(s,p+1).trim();
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (key.compare(C_TYPE, -1) == 0){
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (value.compare(C_TOASCII, -1) == 0) {
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    type = 0;
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else if (value.compare(C_TOUNICODE, -1) == 0){
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    type = 1;
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if (key.compare(C_PASSFAIL, -1) == 0){
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (value.compare(C_PASS, -1) == 0){
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    passfail = 0;
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else if (value.compare(C_FAIL, -1) == 0){
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    passfail = 1;
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if (key.compare(C_DESC, -1) == 0){
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (value.indexOf(C_USESTD3ASCIIRULES, u_strlen(C_USESTD3ASCIIRULES), 0) == -1){
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    option = 1; // not found
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else {
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    option = 0;
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                id.setTo(value, 0, value.indexOf((UChar)0x20));    // space
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if (key.compare(C_NAMEZONE, -1) == 0){
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ExplainCodePointTag(value);
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                namezone.setTo(value);
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if (key.compare(C_NAMEBASE, -1) == 0){
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ExplainCodePointTag(value);
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                namebase.setTo(value);
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // just skip other lines
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Call(); // for last record
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid IdnaConfTest::Test(void)
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  // test nothing...
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid IdnaConfTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/){
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    switch (index) {
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TESTCASE(0,Test);
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        default: name = ""; break;
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
354