1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/*
4********************************************************************************
5*   Copyright (C) 2005-2016, International Business Machines
6*   Corporation and others.  All Rights Reserved.
7********************************************************************************
8*
9* File WINUTIL.CPP
10*
11********************************************************************************
12*/
13
14#include "unicode/utypes.h"
15
16#if U_PLATFORM_HAS_WIN32_API
17
18#if !UCONFIG_NO_FORMATTING
19
20#include "cmemory.h"
21#include "winutil.h"
22#include "locmap.h"
23#include "unicode/uloc.h"
24
25#   define WIN32_LEAN_AND_MEAN
26#   define VC_EXTRALEAN
27#   define NOUSER
28#   define NOSERVICE
29#   define NOIME
30#   define NOMCX
31#   include <windows.h>
32#   include <stdio.h>
33#   include <string.h>
34
35static Win32Utilities::LCIDRecord *lcidRecords = NULL;
36static int32_t lcidCount  = 0;
37static int32_t lcidMax = 0;
38
39// TODO: Note that this test will skip locale names and only hit locales with assigned LCIDs
40BOOL CALLBACK EnumLocalesProc(LPSTR lpLocaleString)
41{
42    char localeID[ULOC_FULLNAME_CAPACITY];
43	int32_t localeIDLen;
44    UErrorCode status = U_ZERO_ERROR;
45
46    if (lcidCount >= lcidMax) {
47        Win32Utilities::LCIDRecord *newRecords = new Win32Utilities::LCIDRecord[lcidMax + 32];
48
49        for (int i = 0; i < lcidMax; i += 1) {
50            newRecords[i] = lcidRecords[i];
51        }
52
53        delete[] lcidRecords;
54        lcidRecords = newRecords;
55        lcidMax += 32;
56    }
57
58    sscanf(lpLocaleString, "%8x", &lcidRecords[lcidCount].lcid);
59
60    localeIDLen = uprv_convertToPosix(lcidRecords[lcidCount].lcid, localeID, UPRV_LENGTHOF(localeID), &status);
61    if (U_SUCCESS(status)) {
62        lcidRecords[lcidCount].localeID = new char[localeIDLen + 1];
63        memcpy(lcidRecords[lcidCount].localeID, localeID, localeIDLen);
64        lcidRecords[lcidCount].localeID[localeIDLen] = 0;
65    } else {
66        lcidRecords[lcidCount].localeID = NULL;
67    }
68
69    lcidCount += 1;
70
71    return TRUE;
72}
73
74// TODO: Note that this test will skip locale names and only hit locales with assigned LCIDs
75Win32Utilities::LCIDRecord *Win32Utilities::getLocales(int32_t &localeCount)
76{
77    LCIDRecord *result;
78
79    EnumSystemLocalesA(EnumLocalesProc, LCID_INSTALLED);
80
81    localeCount = lcidCount;
82    result      = lcidRecords;
83
84    lcidCount = lcidMax = 0;
85    lcidRecords = NULL;
86
87    return result;
88}
89
90void Win32Utilities::freeLocales(LCIDRecord *records)
91{
92    for (int i = 0; i < lcidCount; i++) {
93        delete lcidRecords[i].localeID;
94    }
95    delete[] records;
96}
97
98#endif /* #if !UCONFIG_NO_FORMATTING */
99
100#endif /* U_PLATFORM_HAS_WIN32_API */
101