16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org********************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Copyright (C) 2005-2011, International Business Machines
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Corporation and others.  All Rights Reserved.
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org********************************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* File WINNMTST.CPP
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org********************************************************************************
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if U_PLATFORM_USES_ONLY_WIN32_API
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/format.h"
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/numfmt.h"
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/locid.h"
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h"
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/testlog.h"
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utmscale.h"
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "winnmfmt.h"
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "winutil.h"
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "winnmtst.h"
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h"
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "locmap.h"
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "wintz.h"
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h"
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   define WIN32_LEAN_AND_MEAN
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   define VC_EXTRALEAN
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   define NOUSER
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   define NOSERVICE
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   define NOIME
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   define NOMCX
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   include <windows.h>
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   include <stdio.h>
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   include <time.h>
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   include <float.h>
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#   include <locale.h>
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define NEW_ARRAY(type,count) (type *) uprv_malloc((count) * sizeof(type))
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DELETE_ARRAY(array) uprv_free((void *) (array))
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define STACK_BUFFER_SIZE 32
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LOOP_COUNT 1000
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool initialized = FALSE;
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return a random int64_t where U_INT64_MIN <= ran <= U_INT64_MAX.
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic uint64_t randomInt64(void)
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int64_t ran = 0;
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i;
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!initialized) {
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        srand((unsigned)time(NULL));
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        initialized = TRUE;
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Assume rand has at least 12 bits of precision */
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (i = 0; i < sizeof(ran); i += 1) {
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4);
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ran;
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return a random double where U_DOUBLE_MIN <= ran <= U_DOUBLE_MAX.
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic double randomDouble(void)
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    double ran = 0;
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!initialized) {
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        srand((unsigned)time(NULL));
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        initialized = TRUE;
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i;
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    do {
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Assume rand has at least 12 bits of precision */
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (i = 0; i < sizeof(ran); i += 1) {
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4);
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } while (_isnan(ran));
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org	int64_t numerator = randomInt64();
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org	int64_t denomenator;
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    do {
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        denomenator = randomInt64();
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (denomenator == 0);
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org	ran = (double)numerator / (double)denomenator;
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ran;
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return a random int32_t where U_INT32_MIN <= ran <= U_INT32_MAX.
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic uint32_t randomInt32(void)
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t ran = 0;
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i;
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!initialized) {
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        srand((unsigned)time(NULL));
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        initialized = TRUE;
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Assume rand has at least 12 bits of precision */
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (i = 0; i < sizeof(ran); i += 1) {
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4);
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ran;
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UnicodeString &getWindowsFormat(int32_t lcid, UBool currency, UnicodeString &appendTo, const wchar_t *fmt, ...)
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    wchar_t nStackBuffer[STACK_BUFFER_SIZE];
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    wchar_t *nBuffer = nStackBuffer;
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    va_list args;
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int result;
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    nBuffer[0] = 0x0000;
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Due to the arguments causing a result to be <= 23 characters (+2 for NULL and minus),
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    we don't need to reallocate the buffer. */
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    va_start(args, fmt);
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result = _vsnwprintf(nBuffer, STACK_BUFFER_SIZE, fmt, args);
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    va_end(args);
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Just to make sure of the above statement, we add this assert */
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_ASSERT(result >=0);
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // The following code is not used because _vscwprintf isn't available on MinGW at the moment.
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*if (result < 0) {
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int newLength;
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        va_start(args, fmt);
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        newLength = _vscwprintf(fmt, args);
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        va_end(args);
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        nBuffer = NEW_ARRAY(UChar, newLength + 1);
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        va_start(args, fmt);
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result = _vsnwprintf(nBuffer, newLength + 1, fmt, args);
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        va_end(args);
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }*/
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // vswprintf is sensitive to the locale set by setlocale. For some locales
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // it doesn't use "." as the decimal separator, which is what GetNumberFormatW
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // and GetCurrencyFormatW both expect to see.
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    //
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // To fix this, we scan over the string and replace the first non-digits, except
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // for a leading "-", with a "."
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    //
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Note: (nBuffer[0] == L'-') will evaluate to 1 if there is a leading '-' in the
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // number, and 0 otherwise.
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (wchar_t *p = &nBuffer[nBuffer[0] == L'-']; *p != L'\0'; p += 1) {
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (*p < L'0' || *p > L'9') {
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *p = L'.';
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    wchar_t stackBuffer[STACK_BUFFER_SIZE];
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    wchar_t *buffer = stackBuffer;
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer[0] = 0x0000;
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (currency) {
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result = GetCurrencyFormatW(lcid, 0, nBuffer, NULL, buffer, STACK_BUFFER_SIZE);
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (result == 0) {
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            DWORD lastError = GetLastError();
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (lastError == ERROR_INSUFFICIENT_BUFFER) {
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                int newLength = GetCurrencyFormatW(lcid, 0, nBuffer, NULL, NULL, 0);
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                buffer = NEW_ARRAY(UChar, newLength);
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                buffer[0] = 0x0000;
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                GetCurrencyFormatW(lcid, 0, nBuffer, NULL, buffer, newLength);
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result = GetNumberFormatW(lcid, 0, nBuffer, NULL, buffer, STACK_BUFFER_SIZE);
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (result == 0) {
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            DWORD lastError = GetLastError();
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (lastError == ERROR_INSUFFICIENT_BUFFER) {
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                int newLength = GetNumberFormatW(lcid, 0, nBuffer, NULL, NULL, 0);
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                buffer = NEW_ARRAY(UChar, newLength);
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                buffer[0] = 0x0000;
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                GetNumberFormatW(lcid, 0, nBuffer, NULL, buffer, newLength);
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    appendTo.append(buffer, (int32_t) wcslen(buffer));
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (buffer != stackBuffer) {
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        DELETE_ARRAY(buffer);
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*if (nBuffer != nStackBuffer) {
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        DELETE_ARRAY(nBuffer);
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }*/
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return appendTo;
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void testLocale(const char *localeID, int32_t lcid, NumberFormat *wnf, UBool currency, TestLog *log)
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int n = 0; n < LOOP_COUNT; n += 1) {
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UnicodeString u3Buffer, u6Buffer, udBuffer;
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UnicodeString w3Buffer, w6Buffer, wdBuffer;
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        double d    = randomDouble();
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t i32 = randomInt32();
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int64_t i64 = randomInt64();
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        getWindowsFormat(lcid, currency, wdBuffer, L"%.16f", d);
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        getWindowsFormat(lcid, currency, w3Buffer, L"%I32d", i32);
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        getWindowsFormat(lcid, currency, w6Buffer, L"%I64d", i64);
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        wnf->format(d,   udBuffer);
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (udBuffer.compare(wdBuffer) != 0) {
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UnicodeString locale(localeID);
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log->errln("Double format error for locale " + locale +
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                    ": got " + udBuffer + " expected " + wdBuffer);
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        wnf->format(i32, u3Buffer);
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (u3Buffer.compare(w3Buffer) != 0) {
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UnicodeString locale(localeID);
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log->errln("int32_t format error for locale " + locale +
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                    ": got " + u3Buffer + " expected " + w3Buffer);
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        wnf->format(i64, u6Buffer);
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (u6Buffer.compare(w6Buffer) != 0) {
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UnicodeString locale(localeID);
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log->errln("int64_t format error for locale " + locale +
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                    ": got " + u6Buffer + " expected " + w6Buffer);
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Win32NumberTest::testLocales(TestLog *log)
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t lcidCount = 0;
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Win32Utilities::LCIDRecord *lcidRecords = Win32Utilities::getLocales(lcidCount);
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(int i = 0; i < lcidCount; i += 1) {
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UErrorCode status = U_ZERO_ERROR;
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        char localeID[128];
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // NULL localeID means ICU didn't recognize the lcid
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (lcidRecords[i].localeID == NULL) {
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            continue;
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        strcpy(localeID, lcidRecords[i].localeID);
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (strchr(localeID, '@') > 0) {
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            strcat(localeID, ";");
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            strcat(localeID, "@");
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        strcat(localeID, "compat=host");
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Locale ulocale(localeID);
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        NumberFormat *wnf = NumberFormat::createInstance(ulocale, status);
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        NumberFormat *wcf = NumberFormat::createCurrencyInstance(ulocale, status);
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wnf, FALSE, log);
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wcf, TRUE,  log);
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        char *old_locale = strdup(setlocale(LC_ALL, NULL));
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setlocale(LC_ALL, "German");
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wnf, FALSE, log);
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wcf, TRUE,  log);
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setlocale(LC_ALL, old_locale);
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        free(old_locale);
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete wcf;
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete wnf;
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Win32Utilities::freeLocales(lcidRecords);
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* U_PLATFORM_USES_ONLY_WIN32_API */
324