1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************** 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2005-2009, International Business Machines 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************** 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* File WINNMTST.CPP 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************** 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef U_WINDOWS 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/format.h" 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/numfmt.h" 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/locid.h" 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h" 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/testlog.h" 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utmscale.h" 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "winnmfmt.h" 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "winutil.h" 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "winnmtst.h" 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h" 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "locmap.h" 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "wintz.h" 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uassert.h" 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# define WIN32_LEAN_AND_MEAN 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# define VC_EXTRALEAN 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# define NOUSER 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# define NOSERVICE 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# define NOIME 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# define NOMCX 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# include <windows.h> 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# include <stdio.h> 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# include <time.h> 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# include <float.h> 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# include <locale.h> 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define NEW_ARRAY(type,count) (type *) uprv_malloc((count) * sizeof(type)) 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DELETE_ARRAY(array) uprv_free((void *) (array)) 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define STACK_BUFFER_SIZE 32 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define LOOP_COUNT 1000 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool initialized = FALSE; 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Return a random int64_t where U_INT64_MIN <= ran <= U_INT64_MAX. 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint64_t randomInt64(void) 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int64_t ran = 0; 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!initialized) { 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srand((unsigned)time(NULL)); 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) initialized = TRUE; 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Assume rand has at least 12 bits of precision */ 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (i = 0; i < sizeof(ran); i += 1) { 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4); 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ran; 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Return a random double where U_DOUBLE_MIN <= ran <= U_DOUBLE_MAX. 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static double randomDouble(void) 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double ran = 0; 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!initialized) { 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srand((unsigned)time(NULL)); 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) initialized = TRUE; 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if 0 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) do { 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Assume rand has at least 12 bits of precision */ 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (i = 0; i < sizeof(ran); i += 1) { 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4); 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } while (_isnan(ran)); 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int64_t numerator = randomInt64(); 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int64_t denomenator; 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) do { 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) denomenator = randomInt64(); 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (denomenator == 0); 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ran = (double)numerator / (double)denomenator; 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ran; 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Return a random int32_t where U_INT32_MIN <= ran <= U_INT32_MAX. 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint32_t randomInt32(void) 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t ran = 0; 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!initialized) { 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srand((unsigned)time(NULL)); 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) initialized = TRUE; 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Assume rand has at least 12 bits of precision */ 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (i = 0; i < sizeof(ran); i += 1) { 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4); 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ran; 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UnicodeString &getWindowsFormat(int32_t lcid, UBool currency, UnicodeString &appendTo, const wchar_t *fmt, ...) 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wchar_t nStackBuffer[STACK_BUFFER_SIZE]; 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wchar_t *nBuffer = nStackBuffer; 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_list args; 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int result; 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nBuffer[0] = 0x0000; 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Due to the arguments causing a result to be <= 23 characters (+2 for NULL and minus), 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) we don't need to reallocate the buffer. */ 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_start(args, fmt); 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = _vsnwprintf(nBuffer, STACK_BUFFER_SIZE, fmt, args); 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_end(args); 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Just to make sure of the above statement, we add this assert */ 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_ASSERT(result >=0); 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The following code is not used because _vscwprintf isn't available on MinGW at the moment. 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*if (result < 0) { 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int newLength; 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_start(args, fmt); 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newLength = _vscwprintf(fmt, args); 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_end(args); 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nBuffer = NEW_ARRAY(UChar, newLength + 1); 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_start(args, fmt); 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = _vsnwprintf(nBuffer, newLength + 1, fmt, args); 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_end(args); 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }*/ 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // vswprintf is sensitive to the locale set by setlocale. For some locales 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // it doesn't use "." as the decimal separator, which is what GetNumberFormatW 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // and GetCurrencyFormatW both expect to see. 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // To fix this, we scan over the string and replace the first non-digits, except 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // for a leading "-", with a "." 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Note: (nBuffer[0] == L'-') will evaluate to 1 if there is a leading '-' in the 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // number, and 0 otherwise. 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (wchar_t *p = &nBuffer[nBuffer[0] == L'-']; *p != L'\0'; p += 1) { 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (*p < L'0' || *p > L'9') { 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *p = L'.'; 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wchar_t stackBuffer[STACK_BUFFER_SIZE]; 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wchar_t *buffer = stackBuffer; 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer[0] = 0x0000; 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (currency) { 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = GetCurrencyFormatW(lcid, 0, nBuffer, NULL, buffer, STACK_BUFFER_SIZE); 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result == 0) { 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) DWORD lastError = GetLastError(); 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (lastError == ERROR_INSUFFICIENT_BUFFER) { 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int newLength = GetCurrencyFormatW(lcid, 0, nBuffer, NULL, NULL, 0); 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = NEW_ARRAY(UChar, newLength); 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer[0] = 0x0000; 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) GetCurrencyFormatW(lcid, 0, nBuffer, NULL, buffer, newLength); 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = GetNumberFormatW(lcid, 0, nBuffer, NULL, buffer, STACK_BUFFER_SIZE); 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result == 0) { 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) DWORD lastError = GetLastError(); 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (lastError == ERROR_INSUFFICIENT_BUFFER) { 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int newLength = GetNumberFormatW(lcid, 0, nBuffer, NULL, NULL, 0); 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = NEW_ARRAY(UChar, newLength); 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer[0] = 0x0000; 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) GetNumberFormatW(lcid, 0, nBuffer, NULL, buffer, newLength); 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) appendTo.append(buffer, (int32_t) wcslen(buffer)); 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (buffer != stackBuffer) { 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) DELETE_ARRAY(buffer); 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*if (nBuffer != nStackBuffer) { 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) DELETE_ARRAY(nBuffer); 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }*/ 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return appendTo; 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void testLocale(const char *localeID, int32_t lcid, NumberFormat *wnf, UBool currency, TestLog *log) 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int n = 0; n < LOOP_COUNT; n += 1) { 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString u3Buffer, u6Buffer, udBuffer; 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString w3Buffer, w6Buffer, wdBuffer; 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double d = randomDouble(); 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i32 = randomInt32(); 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int64_t i64 = randomInt64(); 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getWindowsFormat(lcid, currency, wdBuffer, L"%.16f", d); 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getWindowsFormat(lcid, currency, w3Buffer, L"%I32d", i32); 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getWindowsFormat(lcid, currency, w6Buffer, L"%I64d", i64); 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wnf->format(d, udBuffer); 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (udBuffer.compare(wdBuffer) != 0) { 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString locale(localeID); 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) log->errln("Double format error for locale " + locale + 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ": got " + udBuffer + " expected " + wdBuffer); 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wnf->format(i32, u3Buffer); 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (u3Buffer.compare(w3Buffer) != 0) { 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString locale(localeID); 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) log->errln("int32_t format error for locale " + locale + 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ": got " + u3Buffer + " expected " + w3Buffer); 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wnf->format(i64, u6Buffer); 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (u6Buffer.compare(w6Buffer) != 0) { 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString locale(localeID); 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) log->errln("int64_t format error for locale " + locale + 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ": got " + u6Buffer + " expected " + w6Buffer); 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Win32NumberTest::testLocales(TestLog *log) 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t lcidCount = 0; 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Win32Utilities::LCIDRecord *lcidRecords = Win32Utilities::getLocales(lcidCount); 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(int i = 0; i < lcidCount; i += 1) { 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char localeID[128]; 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // NULL localeID means ICU didn't recognize the lcid 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (lcidRecords[i].localeID == NULL) { 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strcpy(localeID, lcidRecords[i].localeID); 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (strchr(localeID, '@') > 0) { 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strcat(localeID, ";"); 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strcat(localeID, "@"); 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strcat(localeID, "compat=host"); 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Locale ulocale(localeID); 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NumberFormat *wnf = NumberFormat::createInstance(ulocale, status); 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NumberFormat *wcf = NumberFormat::createCurrencyInstance(ulocale, status); 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wnf, FALSE, log); 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wcf, TRUE, log); 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if 0 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *old_locale = strdup(setlocale(LC_ALL, NULL)); 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setlocale(LC_ALL, "German"); 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wnf, FALSE, log); 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wcf, TRUE, log); 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setlocale(LC_ALL, old_locale); 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) free(old_locale); 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete wcf; 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete wnf; 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Win32Utilities::freeLocales(lcidRecords); 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_FORMATTING */ 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #ifdef U_WINDOWS */ 324