185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho******************************************************************************
385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*
485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   Copyright (C) 2001-2008, International Business Machines
585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   Corporation and others.  All Rights Reserved.
685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*
785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho******************************************************************************
885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   file name:  trietest.c
985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   encoding:   US-ASCII
1085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   tab size:   8 (not used)
1185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   indentation:4
1285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*
1385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   created on: 2008sep01 (starting from a copy of trietest.c)
1485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   created by: Markus W. Scherer
1585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*/
1685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include <stdio.h>
1885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/utypes.h"
1985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "utrie2.h"
2085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "utrie.h"
2185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "cstring.h"
2285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "cmemory.h"
2385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "udataswp.h"
2485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "cintltst.h"
2585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
2785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid addTrie2Test(TestNode** root);
2985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* Values for setting possibly overlapping, out-of-order ranges of values */
3185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hotypedef struct SetRange {
3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar32 start, limit;
3385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t value;
3485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool overwrite;
3585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} SetRange;
3685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
3885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Values for testing:
3985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * value is set from the previous boundary's limit to before
4085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * this boundary's limit
4185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *
4285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * There must be an entry with limit 0 and the intialValue.
4385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * It may be preceded by an entry with negative limit and the errorValue.
4485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
4585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hotypedef struct CheckRange {
4685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar32 limit;
4785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t value;
4885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} CheckRange;
4985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
5085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic int32_t
5185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoskipSpecialValues(const CheckRange checkRanges[], int32_t countCheckRanges) {
5285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i;
5385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0; i<countCheckRanges && checkRanges[i].limit<=0; ++i) {}
5485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return i;
5585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
5685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
5785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic int32_t
5885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HogetSpecialValues(const CheckRange checkRanges[], int32_t countCheckRanges,
5985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                 uint32_t *pInitialValue, uint32_t *pErrorValue) {
6085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i=0;
6185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(i<countCheckRanges && checkRanges[i].limit<0) {
6285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pErrorValue=checkRanges[i++].value;
6385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
6485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pErrorValue=0xbad;
6585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
6685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(i<countCheckRanges && checkRanges[i].limit==0) {
6785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pInitialValue=checkRanges[i++].value;
6885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
6985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pInitialValue=0;
7085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
7185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return i;
7285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
7385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
7485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* utrie2_enum() callback, modifies a value */
7585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic uint32_t U_CALLCONV
7685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestEnumValue(const void *context, uint32_t value) {
7785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return value^0x5555;
7885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
7985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
8085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* utrie2_enum() callback, verifies a range */
8185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic UBool U_CALLCONV
8285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestEnumRange(const void *context, UChar32 start, UChar32 end, uint32_t value) {
8385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const CheckRange **pb=(const CheckRange **)context;
8485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const CheckRange *b=(*pb)++;
8585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar32 limit=end+1;
8685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
8785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    value^=0x5555;
8885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(start!=(b-1)->limit || limit!=b->limit || value!=b->value) {
8985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_enum() delivers wrong range [U+%04lx..U+%04lx].0x%lx instead of [U+%04lx..U+%04lx].0x%lx\n",
9085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (long)start, (long)end, (long)value,
9185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (long)(b-1)->limit, (long)b->limit-1, (long)b->value);
9285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
9385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return TRUE;
9485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
9585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
9685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
9785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestTrieEnum(const char *testName,
9885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho             const UTrie2 *trie,
9985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho             const CheckRange checkRanges[], int32_t countCheckRanges) {
10085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* skip over special values */
10185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while(countCheckRanges>0 && checkRanges[0].limit<=0) {
10285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ++checkRanges;
10385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        --countCheckRanges;
10485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
10585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_enum(trie, testEnumValue, testEnumRange, &checkRanges);
10685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
10785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
10885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* verify all expected values via UTRIE2_GETxx() */
10985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
11085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestTrieGetters(const char *testName,
11185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                const UTrie2 *trie, UTrie2ValueBits valueBits,
11285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                const CheckRange checkRanges[], int32_t countCheckRanges) {
11385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t initialValue, errorValue;
11485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t value, value2;
11585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar32 start, limit;
11685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i, countSpecials;
11785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
11885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool isFrozen=utrie2_isFrozen(trie);
11985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const char *const typeName= isFrozen ? "frozen trie" : "newTrie";
12085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
12185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    countSpecials=getSpecialValues(checkRanges, countCheckRanges, &initialValue, &errorValue);
12285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
12385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    start=0;
12485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=countSpecials; i<countCheckRanges; ++i) {
12585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        limit=checkRanges[i].limit;
12685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        value=checkRanges[i].value;
12785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
12885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        while(start<limit) {
12985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(isFrozen) {
13085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if(start<=0xffff) {
13185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    if(!U_IS_LEAD(start)) {
13285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        if(valueBits==UTRIE2_16_VALUE_BITS) {
13385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                            value2=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(trie, start);
13485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        } else {
13585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                            value2=UTRIE2_GET32_FROM_U16_SINGLE_LEAD(trie, start);
13685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        }
13785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        if(value!=value2) {
13885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                            log_err("error: %s(%s).fromBMP(U+%04lx)==0x%lx instead of 0x%lx\n",
13985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    typeName, testName, (long)start, (long)value2, (long)value);
14085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        }
14185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
14285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                } else {
14385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    if(valueBits==UTRIE2_16_VALUE_BITS) {
14485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        value2=UTRIE2_GET16_FROM_SUPP(trie, start);
14585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    } else {
14685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        value2=UTRIE2_GET32_FROM_SUPP(trie, start);
14785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
14885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    if(value!=value2) {
14985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        log_err("error: %s(%s).fromSupp(U+%04lx)==0x%lx instead of 0x%lx\n",
15085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                typeName, testName, (long)start, (long)value2, (long)value);
15185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
15285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
15385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if(valueBits==UTRIE2_16_VALUE_BITS) {
15485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    value2=UTRIE2_GET16(trie, start);
15585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                } else {
15685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    value2=UTRIE2_GET32(trie, start);
15785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
15885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if(value!=value2) {
15985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    log_err("error: %s(%s).get(U+%04lx)==0x%lx instead of 0x%lx\n",
16085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                            typeName, testName, (long)start, (long)value2, (long)value);
16185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
16285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
16385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value2=utrie2_get32(trie, start);
16485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(value!=value2) {
16585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: %s(%s).get32(U+%04lx)==0x%lx instead of 0x%lx\n",
16685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        typeName, testName, (long)start, (long)value2, (long)value);
16785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
16885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ++start;
16985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
17085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
17185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
17285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(isFrozen) {
17385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* test linear ASCII range from the data array pointer (access to "internal" field) */
17485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        start=0;
17585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for(i=countSpecials; i<countCheckRanges && start<=0x7f; ++i) {
17685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            limit=checkRanges[i].limit;
17785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value=checkRanges[i].value;
17885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
17985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            while(start<limit && start<=0x7f) {
18085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if(valueBits==UTRIE2_16_VALUE_BITS) {
18185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    value2=trie->data16[start];
18285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                } else {
18385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    value2=trie->data32[start];
18485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
18585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if(value!=value2) {
18685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    log_err("error: %s(%s).asciiData[U+%04lx]==0x%lx instead of 0x%lx\n",
18785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                            typeName, testName, (long)start, (long)value2, (long)value);
18885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
18985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                ++start;
19085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
19185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
19285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        while(start<=0xbf) {
19385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(valueBits==UTRIE2_16_VALUE_BITS) {
19485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                value2=trie->data16[start];
19585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
19685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                value2=trie->data32[start];
19785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
19885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(errorValue!=value2) {
19985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: %s(%s).badData[U+%04lx]==0x%lx instead of 0x%lx\n",
20085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        typeName, testName, (long)start, (long)value2, (long)errorValue);
20185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
20285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ++start;
20385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
20485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
20585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
20685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(0!=strncmp(testName, "dummy", 5) && 0!=strncmp(testName, "trie1", 5)) {
20785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* test values for lead surrogate code units */
20885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for(start=0xd7ff; start<0xdc01; ++start) {
20985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            switch(start) {
21085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case 0xd7ff:
21185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case 0xdc00:
21285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                value=errorValue;
21385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
21485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case 0xd800:
21585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                value=90;
21685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
21785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case 0xd999:
21885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                value=94;
21985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
22085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case 0xdbff:
22185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                value=99;
22285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
22385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            default:
22485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                value=initialValue;
22585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
22685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
22785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(isFrozen && U_IS_LEAD(start)) {
22885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if(valueBits==UTRIE2_16_VALUE_BITS) {
22985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    value2=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(trie, start);
23085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                } else {
23185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    value2=UTRIE2_GET32_FROM_U16_SINGLE_LEAD(trie, start);
23285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
23385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if(value2!=value) {
23485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    log_err("error: %s(%s).LSCU(U+%04lx)==0x%lx instead of 0x%lx\n",
23585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                            typeName, testName, (long)start, (long)value2, (long)value);
23685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
23785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
23885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value2=utrie2_get32FromLeadSurrogateCodeUnit(trie, start);
23985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(value2!=value) {
24085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: %s(%s).lscu(U+%04lx)==0x%lx instead of 0x%lx\n",
24185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        typeName, testName, (long)start, (long)value2, (long)value);
24285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
24385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
24485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
24585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
24685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* test errorValue */
24785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(isFrozen) {
24885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(valueBits==UTRIE2_16_VALUE_BITS) {
24985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value=UTRIE2_GET16(trie, -1);
25085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value2=UTRIE2_GET16(trie, 0x110000);
25185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
25285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value=UTRIE2_GET32(trie, -1);
25385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value2=UTRIE2_GET32(trie, 0x110000);
25485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
25585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(value!=errorValue || value2!=errorValue) {
25685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: %s(%s).get(out of range) != errorValue\n",
25785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    typeName, testName);
25885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
25985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
26085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    value=utrie2_get32(trie, -1);
26185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    value2=utrie2_get32(trie, 0x110000);
26285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(value!=errorValue || value2!=errorValue) {
26385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: %s(%s).get32(out of range) != errorValue\n",
26485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                typeName, testName);
26585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
26685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
26785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
26885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
26985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestTrieUTF16(const char *testName,
27085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho              const UTrie2 *trie, UTrie2ValueBits valueBits,
27185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho              const CheckRange checkRanges[], int32_t countCheckRanges) {
27285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar s[200];
27385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t values[100];
27485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
27585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const UChar *p, *limit;
27685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
27785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t value;
27885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar32 prevCP, c, c2;
27985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i, length, sIndex, countValues;
28085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
28185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* write a string */
28285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    prevCP=0;
28385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    length=countValues=0;
28485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=skipSpecialValues(checkRanges, countCheckRanges); i<countCheckRanges; ++i) {
28585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        value=checkRanges[i].value;
28685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* write three code points */
28785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U16_APPEND_UNSAFE(s, length, prevCP);   /* start of the range */
28885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        values[countValues++]=value;
28985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        c=checkRanges[i].limit;
29085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        prevCP=(prevCP+c)/2;                    /* middle of the range */
29185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U16_APPEND_UNSAFE(s, length, prevCP);
29285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        values[countValues++]=value;
29385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        prevCP=c;
29485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        --c;                                    /* end of the range */
29585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U16_APPEND_UNSAFE(s, length, c);
29685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        values[countValues++]=value;
29785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
29885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    limit=s+length;
29985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
30085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* try forward */
30185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    p=s;
30285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    i=0;
30385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while(p<limit) {
30485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        sIndex=(int32_t)(p-s);
30585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U16_NEXT(s, sIndex, length, c2);
30685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        c=0x33;
30785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(valueBits==UTRIE2_16_VALUE_BITS) {
30885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTRIE2_U16_NEXT16(trie, p, limit, c, value);
30985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
31085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTRIE2_U16_NEXT32(trie, p, limit, c, value);
31185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
31285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(value!=values[i]) {
31385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: wrong value from UTRIE2_NEXT(%s)(U+%04lx): 0x%lx instead of 0x%lx\n",
31485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, (long)c, (long)value, (long)values[i]);
31585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
31685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(c!=c2) {
31785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: wrong code point from UTRIE2_NEXT(%s): U+%04lx != U+%04lx\n",
31885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, (long)c, (long)c2);
31985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            continue;
32085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
32185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ++i;
32285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
32385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
32485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* try backward */
32585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    p=limit;
32685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    i=countValues;
32785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while(s<p) {
32885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        --i;
32985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        sIndex=(int32_t)(p-s);
33085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U16_PREV(s, 0, sIndex, c2);
33185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        c=0x33;
33285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(valueBits==UTRIE2_16_VALUE_BITS) {
33385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTRIE2_U16_PREV16(trie, s, p, c, value);
33485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
33585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTRIE2_U16_PREV32(trie, s, p, c, value);
33685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
33785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(value!=values[i]) {
33885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: wrong value from UTRIE2_PREV(%s)(U+%04lx): 0x%lx instead of 0x%lx\n",
33985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, (long)c, (long)value, (long)values[i]);
34085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
34185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(c!=c2) {
34285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: wrong code point from UTRIE2_PREV(%s): U+%04lx != U+%04lx\n",
34385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, c, c2);
34485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
34585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
34685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
34785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
34885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
34985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestTrieUTF8(const char *testName,
35085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho             const UTrie2 *trie, UTrie2ValueBits valueBits,
35185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho             const CheckRange checkRanges[], int32_t countCheckRanges) {
35285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const uint8_t illegal[]={
35385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xc0, 0x80,                         /* non-shortest U+0000 */
35485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xc1, 0xbf,                         /* non-shortest U+007f */
35585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xc2,                               /* truncated */
35685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xe0, 0x90, 0x80,                   /* non-shortest U+0400 */
35785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xe0, 0xa0,                         /* truncated */
35885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xed, 0xa0, 0x80,                   /* lead surrogate U+d800 */
35985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xed, 0xbf, 0xbf,                   /* trail surrogate U+dfff */
36085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xf0, 0x8f, 0xbf, 0xbf,             /* non-shortest U+ffff */
36185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xf0, 0x90, 0x80,                   /* truncated */
36285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xf4, 0x90, 0x80, 0x80,             /* beyond-Unicode U+110000 */
36385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xf8, 0x80, 0x80, 0x80,             /* truncated */
36485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xf8, 0x80, 0x80, 0x80, 0x80,       /* 5-byte UTF-8 */
36585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xfd, 0xbf, 0xbf, 0xbf, 0xbf,       /* truncated */
36685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xfd, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, /* 6-byte UTF-8 */
36785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xfe,
36885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0xff
36985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
37085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint8_t s[600];
37185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t values[200];
37285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
37385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const uint8_t *p, *limit;
37485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
37585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t initialValue, errorValue;
37685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t value, bytes;
37785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar32 prevCP, c;
37885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i, countSpecials, length, countValues;
37985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t prev8, i8;
38085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
38185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    countSpecials=getSpecialValues(checkRanges, countCheckRanges, &initialValue, &errorValue);
38285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
38385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* write a string */
38485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    prevCP=0;
38585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    length=countValues=0;
38685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* first a couple of trail bytes in lead position */
38785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    s[length++]=0x80;
38885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    values[countValues++]=errorValue;
38985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    s[length++]=0xbf;
39085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    values[countValues++]=errorValue;
39185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    prev8=i8=0;
39285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=countSpecials; i<countCheckRanges; ++i) {
39385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        value=checkRanges[i].value;
39485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* write three legal (or surrogate) code points */
39585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U8_APPEND_UNSAFE(s, length, prevCP);    /* start of the range */
39685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        values[countValues++]=U_IS_SURROGATE(prevCP) ? errorValue : value;
39785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        c=checkRanges[i].limit;
39885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        prevCP=(prevCP+c)/2;                    /* middle of the range */
39985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U8_APPEND_UNSAFE(s, length, prevCP);
40085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        values[countValues++]=U_IS_SURROGATE(prevCP) ? errorValue : value;
40185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        prevCP=c;
40285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        --c;                                    /* end of the range */
40385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U8_APPEND_UNSAFE(s, length, c);
40485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        values[countValues++]=U_IS_SURROGATE(c) ? errorValue : value;
40585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* write an illegal byte sequence */
40685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(i8<sizeof(illegal)) {
40785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            U8_FWD_1(illegal, i8, sizeof(illegal));
40885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            while(prev8<i8) {
40985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                s[length++]=illegal[prev8++];
41085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
41185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            values[countValues++]=errorValue;
41285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
41385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
41485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* write the remaining illegal byte sequences */
41585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while(i8<sizeof(illegal)) {
41685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U8_FWD_1(illegal, i8, sizeof(illegal));
41785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        while(prev8<i8) {
41885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            s[length++]=illegal[prev8++];
41985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
42085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        values[countValues++]=errorValue;
42185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
42285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    limit=s+length;
42385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
42485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* try forward */
42585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    p=s;
42685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    i=0;
42785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while(p<limit) {
42885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        prev8=i8=(int32_t)(p-s);
42985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U8_NEXT(s, i8, length, c);
43085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(valueBits==UTRIE2_16_VALUE_BITS) {
43185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTRIE2_U8_NEXT16(trie, p, limit, value);
43285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
43385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTRIE2_U8_NEXT32(trie, p, limit, value);
43485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
43585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        bytes=0;
43685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(value!=values[i] || i8!=(p-s)) {
43785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            while(prev8<i8) {
43885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                bytes=(bytes<<8)|s[prev8++];
43985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
44085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
44185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(value!=values[i]) {
44285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: wrong value from UTRIE2_U8_NEXT(%s)(%lx->U+%04lx): 0x%lx instead of 0x%lx\n",
44385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, (unsigned long)bytes, (long)c, (long)value, (long)values[i]);
44485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
44585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(i8!=(p-s)) {
44685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: wrong end index from UTRIE2_U8_NEXT(%s)(%lx->U+%04lx): %ld != %ld\n",
44785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, (unsigned long)bytes, (long)c, (long)(p-s), (long)i8);
44885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            continue;
44985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
45085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ++i;
45185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
45285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
45385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* try backward */
45485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    p=limit;
45585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    i=countValues;
45685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while(s<p) {
45785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        --i;
45885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        prev8=i8=(int32_t)(p-s);
45985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        U8_PREV(s, 0, i8, c);
46085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(valueBits==UTRIE2_16_VALUE_BITS) {
46185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTRIE2_U8_PREV16(trie, s, p, value);
46285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
46385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTRIE2_U8_PREV32(trie, s, p, value);
46485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
46585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        bytes=0;
46685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(value!=values[i] || i8!=(p-s)) {
46785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            int32_t k=i8;
46885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            while(k<prev8) {
46985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                bytes=(bytes<<8)|s[k++];
47085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
47185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
47285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(value!=values[i]) {
47385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: wrong value from UTRIE2_U8_PREV(%s)(%lx->U+%04lx): 0x%lx instead of 0x%lx\n",
47485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, (unsigned long)bytes, (long)c, (long)value, (long)values[i]);
47585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
47685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(i8!=(p-s)) {
47785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: wrong end index from UTRIE2_U8_PREV(%s)(%lx->U+%04lx): %ld != %ld\n",
47885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, (unsigned long)bytes, (long)c, (long)(p-s), (long)i8);
47985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            continue;
48085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
48185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
48285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
48385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
48485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
48585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestFrozenTrie(const char *testName,
48685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               UTrie2 *trie, UTrie2ValueBits valueBits,
48785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               const CheckRange checkRanges[], int32_t countCheckRanges) {
48885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode errorCode;
48985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t value, value2;
49085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(!utrie2_isFrozen(trie)) {
49285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_isFrozen(frozen %s) returned FALSE (not frozen)\n",
49385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                testName);
49485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
49585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
49685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieGetters(testName, trie, valueBits, checkRanges, countCheckRanges);
49885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieEnum(testName, trie, checkRanges, countCheckRanges);
49985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieUTF16(testName, trie, valueBits, checkRanges, countCheckRanges);
50085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieUTF8(testName, trie, valueBits, checkRanges, countCheckRanges);
50185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
50285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
50385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    value=utrie2_get32(trie, 1);
50485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32(trie, 1, 234, &errorCode);
50585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    value2=utrie2_get32(trie, 1);
50685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(errorCode!=U_NO_WRITE_PERMISSION || value2!=value) {
50785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_set32(frozen %s) failed: it set %s != U_NO_WRITE_PERMISSION\n",
50885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                testName, u_errorName(errorCode));
50985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
51085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
51185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
51285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
51385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_setRange32(trie, 1, 5, 234, TRUE, &errorCode);
51485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    value2=utrie2_get32(trie, 1);
51585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(errorCode!=U_NO_WRITE_PERMISSION || value2!=value) {
51685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_setRange32(frozen %s) failed: it set %s != U_NO_WRITE_PERMISSION\n",
51785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                testName, u_errorName(errorCode));
51885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
51985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
52085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
52185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
52285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    value=utrie2_get32FromLeadSurrogateCodeUnit(trie, 0xd801);
52385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xd801, 234, &errorCode);
52485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    value2=utrie2_get32FromLeadSurrogateCodeUnit(trie, 0xd801);
52585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(errorCode!=U_NO_WRITE_PERMISSION || value2!=value) {
52685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_set32ForLeadSurrogateCodeUnit(frozen %s) failed: "
52785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                "it set %s != U_NO_WRITE_PERMISSION\n",
52885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                testName, u_errorName(errorCode));
52985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
53085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
53185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
53285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
53385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
53485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestNewTrie(const char *testName, const UTrie2 *trie,
53585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            const CheckRange checkRanges[], int32_t countCheckRanges) {
53685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* The valueBits are ignored for an unfrozen trie. */
53785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieGetters(testName, trie, UTRIE2_COUNT_VALUE_BITS, checkRanges, countCheckRanges);
53885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieEnum(testName, trie, checkRanges, countCheckRanges);
53985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
54085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
54185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
54285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestTrieSerialize(const char *testName,
54385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                  UTrie2 *trie, UTrie2ValueBits valueBits,
54485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                  UBool withSwap,
54585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                  const CheckRange checkRanges[], int32_t countCheckRanges) {
54685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t storage[10000];
54785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t length1, length2, length3;
54885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UTrie2ValueBits otherValueBits;
54985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode errorCode;
55085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
55185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* clone the trie so that the caller can reuse the original */
55285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
55385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    trie=utrie2_clone(trie, &errorCode);
55485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_FAILURE(errorCode)) {
55585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_clone(unfrozen %s) failed - %s\n",
55685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                testName, u_errorName(errorCode));
55785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
55885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
55985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
56085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*
56185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * This is not a loop, but simply a block that we can exit with "break"
56285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * when something goes wrong.
56385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     */
56485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    do {
56585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errorCode=U_ZERO_ERROR;
56685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_serialize(trie, storage, sizeof(storage), &errorCode);
56785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
56885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_serialize(unfrozen %s) set %s != U_ILLEGAL_ARGUMENT_ERROR\n",
56985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, u_errorName(errorCode));
57085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
57185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
57285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errorCode=U_ZERO_ERROR;
57385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_freeze(trie, valueBits, &errorCode);
57485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(U_FAILURE(errorCode) || !utrie2_isFrozen(trie)) {
57585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_freeze(%s) failed: %s isFrozen: %d\n",
57685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, u_errorName(errorCode), utrie2_isFrozen(trie));
57785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
57885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
57985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        otherValueBits= valueBits==UTRIE2_16_VALUE_BITS ? UTRIE2_32_VALUE_BITS : UTRIE2_16_VALUE_BITS;
58085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_freeze(trie, otherValueBits, &errorCode);
58185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
58285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_freeze(already-frozen with other valueBits %s) "
58385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    "set %s != U_ILLEGAL_ARGUMENT_ERROR\n",
58485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, u_errorName(errorCode));
58585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
58685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
58785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errorCode=U_ZERO_ERROR;
58885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(withSwap) {
58985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* clone a frozen trie */
59085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTrie2 *clone=utrie2_clone(trie, &errorCode);
59185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode)) {
59285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: cloning a frozen UTrie2 failed (%s) - %s\n",
59385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        testName, u_errorName(errorCode));
59485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                errorCode=U_ZERO_ERROR;  /* continue with the original */
59585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
59685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                utrie2_close(trie);
59785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                trie=clone;
59885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
59985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
60085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        length1=utrie2_serialize(trie, NULL, 0, &errorCode);
60185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(errorCode!=U_BUFFER_OVERFLOW_ERROR) {
60285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_serialize(%s) preflighting set %s != U_BUFFER_OVERFLOW_ERROR\n",
60385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, u_errorName(errorCode));
60485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
60585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
60685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errorCode=U_ZERO_ERROR;
60785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        length2=utrie2_serialize(trie, storage, sizeof(storage), &errorCode);
60885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
60985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_serialize(%s) needs more memory\n", testName);
61085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
61185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
61285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(U_FAILURE(errorCode)) {
61385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_serialize(%s) failed: %s\n", testName, u_errorName(errorCode));
61485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
61585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
61685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(length1!=length2) {
61785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: trie serialization (%s) lengths different: "
61885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    "preflight vs. serialize\n", testName);
61985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
62085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
62185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
62285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        testFrozenTrie(testName, trie, valueBits, checkRanges, countCheckRanges);
62385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_close(trie);
62485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        trie=NULL;
62585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
62685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(withSwap) {
62785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uint32_t swapped[10000];
62885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            int32_t swappedLength;
62985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
63085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UDataSwapper *ds;
63185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
63285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* swap to opposite-endian */
63385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uprv_memset(swapped, 0x55, length2);
63485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ds=udata_openSwapper(U_IS_BIG_ENDIAN, U_CHARSET_FAMILY,
63585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                 !U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode);
63685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            swappedLength=utrie2_swap(ds, storage, -1, NULL, &errorCode);
63785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode) || swappedLength!=length2) {
63885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_swap(%s to OE preflighting) failed (%s) "
63985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        "or before/after lengths different\n",
64085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        testName, u_errorName(errorCode));
64185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                udata_closeSwapper(ds);
64285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
64385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
64485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            swappedLength=utrie2_swap(ds, storage, length2, swapped, &errorCode);
64585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            udata_closeSwapper(ds);
64685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode) || swappedLength!=length2) {
64785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_swap(%s to OE) failed (%s) or before/after lengths different\n",
64885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        testName, u_errorName(errorCode));
64985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
65085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
65185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
65285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* swap back to platform-endian */
65385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uprv_memset(storage, 0xaa, length2);
65485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ds=udata_openSwapper(!U_IS_BIG_ENDIAN, U_CHARSET_FAMILY,
65585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                 U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode);
65685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            swappedLength=utrie2_swap(ds, swapped, -1, NULL, &errorCode);
65785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode) || swappedLength!=length2) {
65885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_swap(%s to PE preflighting) failed (%s) "
65985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        "or before/after lengths different\n",
66085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        testName, u_errorName(errorCode));
66185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                udata_closeSwapper(ds);
66285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
66385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
66485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            swappedLength=utrie2_swap(ds, swapped, length2, storage, &errorCode);
66585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            udata_closeSwapper(ds);
66685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode) || swappedLength!=length2) {
66785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_swap(%s to PE) failed (%s) or before/after lengths different\n",
66885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        testName, u_errorName(errorCode));
66985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
67085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
67185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
67285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
67385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        trie=utrie2_openFromSerialized(valueBits, storage, length2, &length3, &errorCode);
67485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(U_FAILURE(errorCode)) {
67585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_openFromSerialized(%s) failed, %s\n", testName, u_errorName(errorCode));
67685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
67785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
67885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if((valueBits==UTRIE2_16_VALUE_BITS)!=(trie->data32==NULL)) {
67985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: trie serialization (%s) did not preserve 32-bitness\n", testName);
68085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
68185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
68285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(length2!=length3) {
68385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: trie serialization (%s) lengths different: "
68485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    "serialize vs. unserialize\n", testName);
68585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
68685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
68785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* overwrite the storage that is not supposed to be needed */
68885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_memset((char *)storage+length3, 0xfa, (int32_t)(sizeof(storage)-length3));
68985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
69085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_freeze(trie, valueBits, &errorCode);
69185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(U_FAILURE(errorCode) || !utrie2_isFrozen(trie)) {
69285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_freeze(unserialized %s) failed: %s isFrozen: %d\n",
69385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, u_errorName(errorCode), utrie2_isFrozen(trie));
69485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
69585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
69685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_freeze(trie, otherValueBits, &errorCode);
69785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
69885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_freeze(unserialized with other valueBits %s) "
69985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    "set %s != U_ILLEGAL_ARGUMENT_ERROR\n",
70085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, u_errorName(errorCode));
70185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
70285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
70385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errorCode=U_ZERO_ERROR;
70485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(withSwap) {
70585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* clone an unserialized trie */
70685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTrie2 *clone=utrie2_clone(trie, &errorCode);
70785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode)) {
70885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_clone(unserialized %s) failed - %s\n",
70985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        testName, u_errorName(errorCode));
71085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                errorCode=U_ZERO_ERROR;
71185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                /* no need to break: just test the original trie */
71285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
71385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                utrie2_close(trie);
71485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                trie=clone;
71585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                uprv_memset(storage, 0, sizeof(storage));
71685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
71785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
71885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        testFrozenTrie(testName, trie, valueBits, checkRanges, countCheckRanges);
71985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
72085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* clone-as-thawed an unserialized trie */
72185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTrie2 *clone=utrie2_cloneAsThawed(trie, &errorCode);
72285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode) || utrie2_isFrozen(clone)) {
72385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_cloneAsThawed(unserialized %s) failed - "
72485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        "%s (isFrozen: %d)\n",
72585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        testName, u_errorName(errorCode), clone!=NULL && utrie2_isFrozen(trie));
72685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
72785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
72885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                utrie2_close(trie);
72985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                trie=clone;
73085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
73185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
73285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
73385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uint32_t value, value2;
73485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
73585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value=utrie2_get32(trie, 0xa1);
73685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            utrie2_set32(trie, 0xa1, 789, &errorCode);
73785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value2=utrie2_get32(trie, 0xa1);
73885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            utrie2_set32(trie, 0xa1, value, &errorCode);
73985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode) || value2!=789) {
74085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: modifying a cloneAsThawed UTrie2 (%s) failed - %s\n",
74185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        testName, u_errorName(errorCode));
74285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
74385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
74485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        testNewTrie(testName, trie, checkRanges, countCheckRanges);
74585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } while(0);
74685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
74785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_close(trie);
74885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
74985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
75085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic UTrie2 *
75185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestTrieSerializeAllValueBits(const char *testName,
75285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                              UTrie2 *trie, UBool withClone,
75385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                              const CheckRange checkRanges[], int32_t countCheckRanges) {
75485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char name[40];
75585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
75685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* verify that all the expected values are in the unfrozen trie */
75785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testNewTrie(testName, trie, checkRanges, countCheckRanges);
75885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
75985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*
76085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * Test with both valueBits serializations,
76185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * and that utrie2_serialize() can be called multiple times.
76285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     */
76385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcpy(name, testName);
76485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcat(name, ".16");
76585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieSerialize(name, trie,
76685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                      UTRIE2_16_VALUE_BITS, withClone,
76785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                      checkRanges, countCheckRanges);
76885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
76985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(withClone) {
77085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /*
77185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         * try cloning after the first serialization;
77285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         * clone-as-thawed just to sometimes try it on an unfrozen trie
77385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         */
77485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UErrorCode errorCode=U_ZERO_ERROR;
77585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UTrie2 *clone=utrie2_cloneAsThawed(trie, &errorCode);
77685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(U_FAILURE(errorCode)) {
77785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            log_err("error: utrie2_cloneAsThawed(%s) after serialization failed - %s\n",
77885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    testName, u_errorName(errorCode));
77985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
78085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            utrie2_close(trie);
78185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            trie=clone;
78285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
78385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            testNewTrie(testName, trie, checkRanges, countCheckRanges);
78485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
78585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
78685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
78785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcpy(name, testName);
78885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcat(name, ".32");
78985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieSerialize(name, trie,
79085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                      UTRIE2_32_VALUE_BITS, withClone,
79185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                      checkRanges, countCheckRanges);
79285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
79385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return trie; /* could be the clone */
79485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
79585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
79685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic UTrie2 *
79785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HomakeTrieWithRanges(const char *testName, UBool withClone,
79885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   const SetRange setRanges[], int32_t countSetRanges,
79985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   const CheckRange checkRanges[], int32_t countCheckRanges) {
80085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UTrie2 *trie;
80185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t initialValue, errorValue;
80285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t value;
80385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar32 start, limit;
80485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i;
80585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode errorCode;
80685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool overwrite;
80785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
80885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    log_verbose("\ntesting Trie '%s'\n", testName);
80985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
81085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    getSpecialValues(checkRanges, countCheckRanges, &initialValue, &errorValue);
81185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    trie=utrie2_open(initialValue, errorValue, &errorCode);
81285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_FAILURE(errorCode)) {
81385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_open(%s) failed: %s\n", testName, u_errorName(errorCode));
81485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return NULL;
81585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
81685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
81785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* set values from setRanges[] */
81885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0; i<countSetRanges; ++i) {
81985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(withClone && i==countSetRanges/2) {
82085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* switch to a clone in the middle of setting values */
82185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UTrie2 *clone=utrie2_clone(trie, &errorCode);
82285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode)) {
82385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_clone(%s) failed - %s\n",
82485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        testName, u_errorName(errorCode));
82585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                errorCode=U_ZERO_ERROR;  /* continue with the original */
82685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
82785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                utrie2_close(trie);
82885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                trie=clone;
82985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
83085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
83185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        start=setRanges[i].start;
83285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        limit=setRanges[i].limit;
83385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        value=setRanges[i].value;
83485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        overwrite=setRanges[i].overwrite;
83585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if((limit-start)==1 && overwrite) {
83685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            utrie2_set32(trie, start, value, &errorCode);
83785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
83885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            utrie2_setRange32(trie, start, limit-1, value, overwrite, &errorCode);
83985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
84085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
84185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
84285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* set some values for lead surrogate code units */
84385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xd800, 90, &errorCode);
84485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xd999, 94, &errorCode);
84585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xdbff, 99, &errorCode);
84685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_SUCCESS(errorCode)) {
84785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return trie;
84885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
84985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: setting values into a trie (%s) failed - %s\n",
85085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                testName, u_errorName(errorCode));
85185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_close(trie);
85285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return NULL;
85385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
85485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
85585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
85685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
85785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestTrieRanges(const char *testName, UBool withClone,
85885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               const SetRange setRanges[], int32_t countSetRanges,
85985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               const CheckRange checkRanges[], int32_t countCheckRanges) {
86085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UTrie2 *trie=makeTrieWithRanges(testName, withClone,
86185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    setRanges, countSetRanges,
86285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    checkRanges, countCheckRanges);
86385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(trie!=NULL) {
86485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        trie=testTrieSerializeAllValueBits(testName, trie, withClone,
86585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                           checkRanges, countCheckRanges);
86685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_close(trie);
86785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
86885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
86985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
87085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* test data ----------------------------------------------------------------*/
87185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
87285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* set consecutive ranges, even with value 0 */
87385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const SetRange
87485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HosetRanges1[]={
87585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0,        0x40,     0,      FALSE },
87685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x40,     0xe7,     0x1234, FALSE },
87785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xe7,     0x3400,   0,      FALSE },
87885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x3400,   0x9fa6,   0x6162, FALSE },
87985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x9fa6,   0xda9e,   0x3132, FALSE },
88085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xdada,   0xeeee,   0x87ff, FALSE },
88185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xeeee,   0x11111,  1,      FALSE },
88285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x11111,  0x44444,  0x6162, FALSE },
88385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x44444,  0x60003,  0,      FALSE },
88485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0003,  0xf0004,  0xf,    FALSE },
88585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0004,  0xf0006,  0x10,   FALSE },
88685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0006,  0xf0007,  0x11,   FALSE },
88785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0007,  0xf0040,  0x12,   FALSE },
88885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0040,  0x110000, 0,      FALSE }
88985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
89085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
89185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const CheckRange
89285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckRanges1[]={
89385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0,        0 },
89485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x40,     0 },
89585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xe7,     0x1234 },
89685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x3400,   0 },
89785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x9fa6,   0x6162 },
89885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xda9e,   0x3132 },
89985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xdada,   0 },
90085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xeeee,   0x87ff },
90185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x11111,  1 },
90285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x44444,  0x6162 },
90385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0003,  0 },
90485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0004,  0xf },
90585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0006,  0x10 },
90685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0007,  0x11 },
90785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xf0040,  0x12 },
90885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x110000, 0 }
90985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
91085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
91185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* set some interesting overlapping ranges */
91285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const SetRange
91385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HosetRanges2[]={
91485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x21,     0x7f,     0x5555, TRUE },
91585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2f800,  0x2fedc,  0x7a,   TRUE },
91685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x72,     0xdd,     3,      TRUE },
91785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xdd,     0xde,     4,      FALSE },
91885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x201,    0x240,    6,      TRUE },  /* 3 consecutive blocks with the same pattern but */
91985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x241,    0x280,    6,      TRUE },  /* discontiguous value ranges, testing utrie2_enum() */
92085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x281,    0x2c0,    6,      TRUE },
92185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2f987,  0x2fa98,  5,      TRUE },
92285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2f777,  0x2f883,  0,      TRUE },
92385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2f900,  0x2ffaa,  1,      FALSE },
92485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffaa,  0x2ffab,  2,      TRUE },
92585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffbb,  0x2ffc0,  7,      TRUE }
92685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
92785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
92885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const CheckRange
92985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckRanges2[]={
93085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0,        0 },
93185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x21,     0 },
93285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x72,     0x5555 },
93385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xdd,     3 },
93485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xde,     4 },
93585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x201,    0 },
93685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x240,    6 },
93785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x241,    0 },
93885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x280,    6 },
93985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x281,    0 },
94085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2c0,    6 },
94185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2f883,  0 },
94285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2f987,  0x7a },
94385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2fa98,  5 },
94485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2fedc,  0x7a },
94585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffaa,  1 },
94685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffab,  2 },
94785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffbb,  0 },
94885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffc0,  7 },
94985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x110000, 0 }
95085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
95185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
95285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const CheckRange
95385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckRanges2_d800[]={
95485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x10000,  0 },
95585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x10400,  0 }
95685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
95785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
95885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const CheckRange
95985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckRanges2_d87e[]={
96085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2f800,  6 },
96185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2f883,  0 },
96285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2f987,  0x7a },
96385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2fa98,  5 },
96485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2fc00,  0x7a }
96585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
96685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
96785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const CheckRange
96885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckRanges2_d87f[]={
96985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2fc00,  0 },
97085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2fedc,  0x7a },
97185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffaa,  1 },
97285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffab,  2 },
97385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffbb,  0 },
97485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x2ffc0,  7 },
97585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x30000,  0 }
97685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
97785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
97885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const CheckRange
97985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckRanges2_dbff[]={
98085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x10fc00, 0 },
98185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x110000, 0 }
98285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
98385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
98485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* use a non-zero initial value */
98585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const SetRange
98685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HosetRanges3[]={
98785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x31,     0xa4,     1, FALSE },
98885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x3400,   0x6789,   2, FALSE },
98985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x8000,   0x89ab,   9, TRUE },
99085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x9000,   0xa000,   4, TRUE },
99185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xabcd,   0xbcde,   3, TRUE },
99285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x55555,  0x110000, 6, TRUE },  /* highStart<U+ffff with non-initialValue */
99385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xcccc,   0x55555,  6, TRUE }
99485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
99585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
99685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const CheckRange
99785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckRanges3[]={
99885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0,        9 },  /* non-zero initialValue */
99985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x31,     9 },
100085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xa4,     1 },
100185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x3400,   9 },
100285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x6789,   2 },
100385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x9000,   9 },
100485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xa000,   4 },
100585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xabcd,   9 },
100685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xbcde,   3 },
100785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0xcccc,   9 },
100885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x110000, 6 }
100985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
101085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
101185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* empty or single-value tries, testing highStart==0 */
101285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const SetRange
101385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HosetRangesEmpty[]={
101485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0,        0,        0, FALSE },  /* need some values for it to compile */
101585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
101685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
101785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const CheckRange
101885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckRangesEmpty[]={
101985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0,        3 },
102085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x110000, 3 }
102185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
102285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
102385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const SetRange
102485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HosetRangesSingleValue[]={
102585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0,        0x110000, 5, TRUE },
102685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
102785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
102885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const CheckRange
102985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckRangesSingleValue[]={
103085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0,        3 },
103185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { 0x110000, 5 }
103285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
103385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
103485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
103585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTrieTest(void) {
103685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieRanges("set1", FALSE,
103785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        setRanges1, LENGTHOF(setRanges1),
103885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRanges1, LENGTHOF(checkRanges1));
103985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieRanges("set2-overlap", FALSE,
104085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        setRanges2, LENGTHOF(setRanges2),
104185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRanges2, LENGTHOF(checkRanges2));
104285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieRanges("set3-initial-9", FALSE,
104385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        setRanges3, LENGTHOF(setRanges3),
104485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRanges3, LENGTHOF(checkRanges3));
104585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieRanges("set-empty", FALSE,
104685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        setRangesEmpty, 0,
104785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRangesEmpty, LENGTHOF(checkRangesEmpty));
104885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieRanges("set-single-value", FALSE,
104985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        setRangesSingleValue, LENGTHOF(setRangesSingleValue),
105085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRangesSingleValue, LENGTHOF(checkRangesSingleValue));
105185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
105285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrieRanges("set2-overlap.withClone", TRUE,
105385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        setRanges2, LENGTHOF(setRanges2),
105485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRanges2, LENGTHOF(checkRanges2));
105585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
105685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
105785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
105885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoEnumNewTrieForLeadSurrogateTest(void) {
105985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const char *const testName="enum-for-lead";
106085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UTrie2 *trie=makeTrieWithRanges(testName, FALSE,
106185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    setRanges2, LENGTHOF(setRanges2),
106285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    checkRanges2, LENGTHOF(checkRanges2));
106385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while(trie!=NULL) {
106485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        const CheckRange *checkRanges;
106585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
106685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRanges=checkRanges2_d800+1;
106785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_enumForLeadSurrogate(trie, 0xd800,
106885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    testEnumValue, testEnumRange,
106985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    &checkRanges);
107085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRanges=checkRanges2_d87e+1;
107185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_enumForLeadSurrogate(trie, 0xd87e,
107285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    testEnumValue, testEnumRange,
107385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    &checkRanges);
107485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRanges=checkRanges2_d87f+1;
107585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_enumForLeadSurrogate(trie, 0xd87f,
107685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    testEnumValue, testEnumRange,
107785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    &checkRanges);
107885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        checkRanges=checkRanges2_dbff+1;
107985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_enumForLeadSurrogate(trie, 0xdbff,
108085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    testEnumValue, testEnumRange,
108185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                    &checkRanges);
108285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(!utrie2_isFrozen(trie)) {
108385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UErrorCode errorCode=U_ZERO_ERROR;
108485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            utrie2_freeze(trie, UTRIE2_16_VALUE_BITS, &errorCode);
108585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(U_FAILURE(errorCode)) {
108685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_freeze(%s) failed\n", testName);
108785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                utrie2_close(trie);
108885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return;
108985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
109085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
109185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            utrie2_close(trie);
109285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
109385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
109485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
109585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
109685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
109785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* test utrie2_openDummy() -------------------------------------------------- */
109885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
109985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
110085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HodummyTest(UTrie2ValueBits valueBits) {
110185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    CheckRange
110285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    checkRanges[]={
110385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { -1,       0 },
110485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0,        0 },
110585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0x110000, 0 }
110685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
110785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
110885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UTrie2 *trie;
110985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode errorCode;
111085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
111185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const char *testName;
111285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t initialValue, errorValue;
111385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
111485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(valueBits==UTRIE2_16_VALUE_BITS) {
111585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        testName="dummy.16";
111685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        initialValue=0x313;
111785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errorValue=0xaffe;
111885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
111985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        testName="dummy.32";
112085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        initialValue=0x01234567;
112185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errorValue=0x89abcdef;
112285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
112385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    checkRanges[0].value=errorValue;
112485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    checkRanges[1].value=checkRanges[2].value=initialValue;
112585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
112685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
112785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    trie=utrie2_openDummy(valueBits, initialValue, errorValue, &errorCode);
112885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_FAILURE(errorCode)) {
112985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("utrie2_openDummy(valueBits=%d) failed - %s\n", valueBits, u_errorName(errorCode));
113085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
113185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
113285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
113385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testFrozenTrie(testName, trie, valueBits, checkRanges, LENGTHOF(checkRanges));
113485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_close(trie);
113585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
113685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
113785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
113885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoDummyTrieTest(void) {
113985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    dummyTest(UTRIE2_16_VALUE_BITS);
114085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    dummyTest(UTRIE2_32_VALUE_BITS);
114185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
114285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
114385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* test builder memory management ------------------------------------------- */
114485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
114585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
114685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoFreeBlocksTest(void) {
114785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const CheckRange
114885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    checkRanges[]={
114985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0,        1 },
115085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0x740,    1 },
115185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0x780,    2 },
115285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0x880,    3 },
115385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0x110000, 1 }
115485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
115585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const char *const testName="free-blocks";
115685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
115785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UTrie2 *trie;
115885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i;
115985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode errorCode;
116085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
116185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
116285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    trie=utrie2_open(1, 0xbad, &errorCode);
116385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_FAILURE(errorCode)) {
116485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_open(%s) failed: %s\n", testName, u_errorName(errorCode));
116585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
116685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
116785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
116885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*
116985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * Repeatedly set overlapping same-value ranges to stress the free-data-block management.
117085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * If it fails, it will overflow the data array.
117185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     */
117285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0; i<(0x120000>>UTRIE2_SHIFT_2)/2; ++i) {
117385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_setRange32(trie, 0x740, 0x840-1, 1, TRUE, &errorCode);
117485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_setRange32(trie, 0x780, 0x880-1, 1, TRUE, &errorCode);
117585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_setRange32(trie, 0x740, 0x840-1, 2, TRUE, &errorCode);
117685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_setRange32(trie, 0x780, 0x880-1, 3, TRUE, &errorCode);
117785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
117885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* make blocks that will be free during compaction */
117985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_setRange32(trie, 0x1000, 0x3000-1, 2, TRUE, &errorCode);
118085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_setRange32(trie, 0x2000, 0x4000-1, 3, TRUE, &errorCode);
118185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_setRange32(trie, 0x1000, 0x4000-1, 1, TRUE, &errorCode);
118285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* set some values for lead surrogate code units */
118385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xd800, 90, &errorCode);
118485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xd999, 94, &errorCode);
118585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xdbff, 99, &errorCode);
118685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_FAILURE(errorCode)) {
118785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: setting lots of ranges into a trie (%s) failed - %s\n",
118885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                testName, u_errorName(errorCode));
118985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_close(trie);
119085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
119185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
119285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
119385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    trie=testTrieSerializeAllValueBits(testName, trie, FALSE,
119485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                       checkRanges, LENGTHOF(checkRanges));
119585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_close(trie);
119685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
119785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
119885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
119985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoGrowDataArrayTest(void) {
120085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const CheckRange
120185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    checkRanges[]={
120285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0,        1 },
120385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0x720,    2 },
120485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0x7a0,    3 },
120585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0x8a0,    4 },
120685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 0x110000, 5 }
120785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
120885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const char *const testName="grow-data";
120985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
121085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UTrie2 *trie;
121185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i;
121285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode errorCode;
121385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
121485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
121585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    trie=utrie2_open(1, 0xbad, &errorCode);
121685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_FAILURE(errorCode)) {
121785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_open(%s) failed: %s\n", testName, u_errorName(errorCode));
121885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
121985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
122085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
122185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*
122285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * Use utrie2_set32() not utrie2_setRange32() to write non-initialValue-data.
122385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * Should grow/reallocate the data array to a sufficient length.
122485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     */
122585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0; i<0x1000; ++i) {
122685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_set32(trie, i, 2, &errorCode);
122785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
122885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0x720; i<0x1100; ++i) { /* some overlap */
122985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_set32(trie, i, 3, &errorCode);
123085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
123185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0x7a0; i<0x900; ++i) {
123285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_set32(trie, i, 4, &errorCode);
123385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
123485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0x8a0; i<0x110000; ++i) {
123585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_set32(trie, i, 5, &errorCode);
123685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
123785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0xd800; i<0xdc00; ++i) {
123885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_set32ForLeadSurrogateCodeUnit(trie, i, 1, &errorCode);
123985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
124085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* set some values for lead surrogate code units */
124185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xd800, 90, &errorCode);
124285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xd999, 94, &errorCode);
124385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_set32ForLeadSurrogateCodeUnit(trie, 0xdbff, 99, &errorCode);
124485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_FAILURE(errorCode)) {
124585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: setting lots of values into a trie (%s) failed - %s\n",
124685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                testName, u_errorName(errorCode));
124785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie2_close(trie);
124885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
124985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
125085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
125185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    trie=testTrieSerializeAllValueBits(testName, trie, FALSE,
125285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                          checkRanges, LENGTHOF(checkRanges));
125385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_close(trie);
125485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
125585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
125685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* versions 1 and 2 --------------------------------------------------------- */
125785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
125885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
125985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoGetVersionTest(void) {
126085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t data[4];
126185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if( /* version 1 */
126285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x54726965, 1!=utrie2_getVersion(data, sizeof(data), FALSE)) ||
126385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x54726965, 1!=utrie2_getVersion(data, sizeof(data), TRUE)) ||
126485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x65697254, 0!=utrie2_getVersion(data, sizeof(data), FALSE)) ||
126585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x65697254, 1!=utrie2_getVersion(data, sizeof(data), TRUE)) ||
126685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* version 2 */
126785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x54726932, 2!=utrie2_getVersion(data, sizeof(data), FALSE)) ||
126885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x54726932, 2!=utrie2_getVersion(data, sizeof(data), TRUE)) ||
126985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x32697254, 0!=utrie2_getVersion(data, sizeof(data), FALSE)) ||
127085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x32697254, 2!=utrie2_getVersion(data, sizeof(data), TRUE)) ||
127185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* illegal arguments */
127285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x54726932, 0!=utrie2_getVersion(NULL, sizeof(data), FALSE)) ||
127385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x54726932, 0!=utrie2_getVersion(data, 3, FALSE)) ||
127485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x54726932, 0!=utrie2_getVersion((char *)data+1, sizeof(data), FALSE)) ||
127585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* unknown signature values */
127685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x11223344, 0!=utrie2_getVersion(data, sizeof(data), FALSE)) ||
127785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (data[0]=0x54726933, 0!=utrie2_getVersion(data, sizeof(data), FALSE))
127885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    ) {
127985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie2_getVersion() is not working as expected\n");
128085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
128185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
128285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
128385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic UNewTrie *
128485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HomakeNewTrie1WithRanges(const char *testName,
128585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                       const SetRange setRanges[], int32_t countSetRanges,
128685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                       const CheckRange checkRanges[], int32_t countCheckRanges) {
128785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UNewTrie *newTrie;
128885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t initialValue, errorValue;
128985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t value;
129085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar32 start, limit;
129185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i;
129285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode errorCode;
129385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool overwrite, ok;
129485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
129585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    log_verbose("\ntesting Trie '%s'\n", testName);
129685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
129785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    getSpecialValues(checkRanges, countCheckRanges, &initialValue, &errorValue);
129885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    newTrie=utrie_open(NULL, NULL, 2000,
129985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                       initialValue, initialValue,
130085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                       FALSE);
130185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_FAILURE(errorCode)) {
130285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie_open(%s) failed: %s\n", testName, u_errorName(errorCode));
130385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return NULL;
130485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
130585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
130685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* set values from setRanges[] */
130785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    ok=TRUE;
130885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0; i<countSetRanges; ++i) {
130985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        start=setRanges[i].start;
131085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        limit=setRanges[i].limit;
131185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        value=setRanges[i].value;
131285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        overwrite=setRanges[i].overwrite;
131385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if((limit-start)==1 && overwrite) {
131485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ok&=utrie_set32(newTrie, start, value);
131585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
131685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ok&=utrie_setRange32(newTrie, start, limit, value, overwrite);
131785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
131885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
131985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(ok) {
132085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return newTrie;
132185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
132285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: setting values into a trie1 (%s) failed\n", testName);
132385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie_close(newTrie);
132485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return NULL;
132585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
132685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
132785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
132885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
132985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HotestTrie2FromTrie1(const char *testName,
133085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   const SetRange setRanges[], int32_t countSetRanges,
133185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   const CheckRange checkRanges[], int32_t countCheckRanges) {
133285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t memory1_16[3000], memory1_32[3000];
133385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t length16, length32;
133485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar lead;
133585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
133685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char name[40];
133785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
133885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UNewTrie *newTrie1_16, *newTrie1_32;
133985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UTrie trie1_16, trie1_32;
134085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UTrie2 *trie2;
134185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t initialValue, errorValue;
134285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode errorCode;
134385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
134485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    newTrie1_16=makeNewTrie1WithRanges(testName,
134585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                       setRanges, countSetRanges,
134685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                       checkRanges, countCheckRanges);
134785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(newTrie1_16==NULL) {
134885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
134985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
135085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    newTrie1_32=utrie_clone(NULL, newTrie1_16, NULL, 0);
135185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(newTrie1_32==NULL) {
135285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrie_close(newTrie1_16);
135385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
135485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
135585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    errorCode=U_ZERO_ERROR;
135685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    length16=utrie_serialize(newTrie1_16, memory1_16, sizeof(memory1_16),
135785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                             NULL, TRUE, &errorCode);
135885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    length32=utrie_serialize(newTrie1_32, memory1_32, sizeof(memory1_32),
135985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                             NULL, FALSE, &errorCode);
136085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie_unserialize(&trie1_16, memory1_16, length16, &errorCode);
136185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie_unserialize(&trie1_32, memory1_32, length32, &errorCode);
136285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie_close(newTrie1_16);
136385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie_close(newTrie1_32);
136485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_FAILURE(errorCode)) {
136585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        log_err("error: utrie_serialize or unserialize(%s) failed: %s\n",
136685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                testName, u_errorName(errorCode));
136785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
136885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
136985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
137085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    getSpecialValues(checkRanges, countCheckRanges, &initialValue, &errorValue);
137185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
137285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcpy(name, testName);
137385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcat(name, ".16");
137485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    trie2=utrie2_fromUTrie(&trie1_16, errorValue, &errorCode);
137585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_SUCCESS(errorCode)) {
137685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        testFrozenTrie(name, trie2, UTRIE2_16_VALUE_BITS, checkRanges, countCheckRanges);
137785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for(lead=0xd800; lead<0xdc00; ++lead) {
137885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uint32_t value1, value2;
137985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value1=UTRIE_GET16_FROM_LEAD(&trie1_16, lead);
138085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value2=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(trie2, lead);
138185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(value1!=value2) {
138285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_fromUTrie(%s) wrong value %ld!=%ld "
138385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        "from lead surrogate code unit U+%04lx\n",
138485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        name, (long)value2, (long)value1, (long)lead);
138585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
138685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
138785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
138885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
138985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_close(trie2);
139085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
139185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcpy(name, testName);
139285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcat(name, ".32");
139385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    trie2=utrie2_fromUTrie(&trie1_32, errorValue, &errorCode);
139485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(U_SUCCESS(errorCode)) {
139585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        testFrozenTrie(name, trie2, UTRIE2_32_VALUE_BITS, checkRanges, countCheckRanges);
139685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for(lead=0xd800; lead<0xdc00; ++lead) {
139785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uint32_t value1, value2;
139885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value1=UTRIE_GET32_FROM_LEAD(&trie1_32, lead);
139985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            value2=UTRIE2_GET32_FROM_U16_SINGLE_LEAD(trie2, lead);
140085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(value1!=value2) {
140185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                log_err("error: utrie2_fromUTrie(%s) wrong value %ld!=%ld "
140285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        "from lead surrogate code unit U+%04lx\n",
140385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        name, (long)value2, (long)value1, (long)lead);
140485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                break;
140585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
140685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
140785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
140885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrie2_close(trie2);
140985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
141085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
141185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
141285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTrie12ConversionTest(void) {
141385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    testTrie2FromTrie1("trie1->trie2",
141485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                       setRanges2, LENGTHOF(setRanges2),
141585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                       checkRanges2, LENGTHOF(checkRanges2));
141685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
141785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
141885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
141985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoaddTrie2Test(TestNode** root) {
142085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    addTest(root, &TrieTest, "tsutil/trie2test/TrieTest");
142185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    addTest(root, &EnumNewTrieForLeadSurrogateTest,
142285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                  "tsutil/trie2test/EnumNewTrieForLeadSurrogateTest");
142385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    addTest(root, &DummyTrieTest, "tsutil/trie2test/DummyTrieTest");
142485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    addTest(root, &FreeBlocksTest, "tsutil/trie2test/FreeBlocksTest");
142585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    addTest(root, &GrowDataArrayTest, "tsutil/trie2test/GrowDataArrayTest");
142685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    addTest(root, &GetVersionTest, "tsutil/trie2test/GetVersionTest");
142785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    addTest(root, &Trie12ConversionTest, "tsutil/trie2test/Trie12ConversionTest");
142885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
1429