ReactOS 0.4.16-dev-853-g88d9285
GetLocaleInfoA.cpp
Go to the documentation of this file.
1//
2// GetLocaleInfoA.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Defines the CRT-internal GetLocaleInfoA implementation.
7//
8#include <corecrt_internal.h>
9
10
11
12// Wraps a call to GetLocaleInfoEx and translates the result into a narrow string.
13_Success_(return > 0)
14static int __cdecl InternalGetLocaleInfoA(
20 )
21{
22 _LocaleUpdate locale_update(locale);
23
24 int const code_page = locale_update.GetLocaleT()->locinfo->_public._locale_lc_codepage;
25
27 if (buffer_size == 0)
28 return 0;
29
30 __crt_scoped_stack_ptr<wchar_t> const buffer(_malloca_crt_t(wchar_t, buffer_size));
31 if (buffer.get() == nullptr)
32 return 0;
33
35 return 0;
36
37 // Convert from wide to narrow strings:
40 0,
41 buffer.get(),
42 -1,
43 result_size != 0 ? result : nullptr,
45 nullptr,
46 nullptr);
47}
48
49
50
51// Gets locale information appropriate for use in the setlocale initialization
52// functions. In particular, wide locale strings can be converted to narrow
53// strings or numeric values depending on the value of the lc_type parameter.
54//
55// The void_result must be reinterpretable as a pointer to one of the following
56// types, depending on the value of LC_TYPE:
57//
58// * LC_STR_TYPE: char*
59// * LC_WSTR_TYPE: wchar_t*
60// * LC_INT_TYPE: unsigned char
61//
62// For the first two cases, where a pointer to a pointer is passed, if the
63// function succeeds, the caller is responsible for freeing the pointed-to
64// buffer.
65//
66// Returns 0 on success; -1 on failure.
67//
68// Future optimization: When converting a large number of wide strings to
69// multibyte, we do not need to query the size of the result. We can convert
70// them one after another into a large character buffer.
72 _locale_t const locale,
73 int const lc_type,
74 wchar_t const* const locale_name,
75 LCTYPE const locale_type,
76 void* const void_result
77 )
78{
79 *static_cast<void**>(void_result) = nullptr;
80
81 if (lc_type == LC_STR_TYPE)
82 {
83 char** const char_result = static_cast<char**>(void_result);
84
85 int const local_buffer_size = 128;
86 char local_buffer[local_buffer_size];
87
88 int const local_length = InternalGetLocaleInfoA(
89 locale, locale_name, locale_type, local_buffer, local_buffer_size);
90
91 if (local_length != 0)
92 {
93 *char_result = _calloc_crt_t(char, local_length).detach();
94 if (*char_result == nullptr)
95 return -1;
96
97 _ERRCHECK(strncpy_s(*char_result, local_length, local_buffer, local_length - 1));
98 return 0;
99 }
100
102 return -1;
103
104 // If the buffer size was too small, compute the required size and use a
105 // dynamically allocated buffer:
106 int const required_length = InternalGetLocaleInfoA(
107 locale, locale_name, locale_type, nullptr, 0);
108
109 if (required_length == 0)
110 return -1;
111
112 __crt_unique_heap_ptr<char> dynamic_buffer(_calloc_crt_t(char, required_length));
113 if (dynamic_buffer.get() == nullptr)
114 return -1;
115
116 int const actual_length = InternalGetLocaleInfoA(
117 locale, locale_name, locale_type, dynamic_buffer.get(), required_length);
118
119 if (actual_length == 0)
120 return -1;
121
122 *char_result = dynamic_buffer.detach();
123 return 0;
124 }
125 else if (lc_type == LC_WSTR_TYPE)
126 {
127 wchar_t** const wchar_result = static_cast<wchar_t**>(void_result);
128
129 int const required_length = __acrt_GetLocaleInfoEx(locale_name, locale_type, nullptr, 0);
130 if (required_length == 0)
131 return -1;
132
133 __crt_unique_heap_ptr<wchar_t> dynamic_buffer(_calloc_crt_t(wchar_t, required_length));
134 if (dynamic_buffer.get() == nullptr)
135 return -1;
136
137 int const actual_length = __acrt_GetLocaleInfoEx(
138 locale_name, locale_type, dynamic_buffer.get(), required_length);
139
140 if (actual_length == 0)
141 return -1;
142
143 *wchar_result = dynamic_buffer.detach();
144 return 0;
145 }
146 else if (lc_type == LC_INT_TYPE)
147 {
148 unsigned char* const uchar_result = static_cast<unsigned char*>(void_result);
149
150 DWORD value = 0;
151 int const actual_length = __acrt_GetLocaleInfoEx(
153 locale_type | LOCALE_RETURN_NUMBER,
154 reinterpret_cast<wchar_t*>(&value),
155 sizeof(value) / sizeof(wchar_t));
156
157 if (actual_length == 0)
158 return -1;
159
160 *uchar_result = static_cast<unsigned char>(value);
161 return 0;
162 }
163
164 return -1;
165}
int __cdecl __acrt_GetLocaleInfoA(_locale_t const locale, int const lc_type, wchar_t const *const locale_name, LCTYPE const locale_type, void *const void_result)
PCWSTR const LCTYPE const int const result_size
int const code_page
return __acrt_WideCharToMultiByte(code_page, 0, buffer.get(), -1, result_size !=0 ? result :nullptr, result_size, nullptr, nullptr)
PCWSTR const LCTYPE const locale_type
int const buffer_size
#define __cdecl
Definition: accygwin.h:79
Definition: _locale.h:75
int WINAPI __acrt_GetLocaleInfoEx(_In_opt_ LPCWSTR locale_name, _In_ LCTYPE lc_type, _Out_writes_opt_(data_count) LPWSTR data, _In_ int data_count)
#define LC_WSTR_TYPE
#define LC_INT_TYPE
#define _ERRCHECK(e)
#define LC_STR_TYPE
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint buffer
Definition: glext.h:5915
GLuint64EXT * result
Definition: glext.h:11304
#define _Out_writes_z_(s)
Definition: no_sal2.h:180
#define _Success_(c)
Definition: no_sal2.h:84
strncpy_s
Definition: string.h:335
const uint16_t * PCWSTR
Definition: typedefs.h:57
Definition: pdh_main.c:96
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD LCTYPE
Definition: winnls.h:519
#define const
Definition: zconf.h:233