WindowsGlobalizationAdapter.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeBasePch.h"
  6. #include "WindowsGlobalizationAdapter.h"
  7. #if defined(ENABLE_INTL_OBJECT) || defined(ENABLE_ES6_CHAR_CLASSIFIER)
  8. #ifdef INTL_WINGLOB
  9. #include "strsafe.h"
  10. #define __WRL_ASSERT__(cond) Assert(cond)
  11. #include <wrl\implements.h>
  12. #ifdef NTBUILD
  13. using namespace Windows::Globalization;
  14. using namespace Windows::Foundation::Collections;
  15. #else
  16. using namespace ABI::Windows::Globalization;
  17. using namespace ABI::Windows::Foundation::Collections;
  18. #endif
  19. #endif // INTL_WINGLOB
  20. #define IfFailThrowHr(op) \
  21. if (FAILED(hr=(op))) \
  22. { \
  23. JavascriptError::MapAndThrowError(scriptContext, hr);\
  24. } \
  25. #define IfNullReturnError(EXPR, ERROR) do { if (!(EXPR)) { return (ERROR); } } while(FALSE)
  26. #define IfFailedReturn(EXPR) do { hr = (EXPR); if (FAILED(hr)) { return hr; }} while(FALSE)
  27. #define IfFailedSetErrorCodeAndReturn(EXPR, hrVariable) do { hr = (EXPR); if (FAILED(hr)) { hrVariable = hr; return hr; }} while(FALSE)
  28. #define IfFailedGoLabel(expr, label) if (FAILED(expr)) { goto label; }
  29. #define IfFailedGo(expr) IfFailedGoLabel(expr, LReturn)
  30. namespace Js
  31. {
  32. #ifdef INTL_WINGLOB
  33. #ifdef ENABLE_INTL_OBJECT
  34. class HSTRINGIterator : public Microsoft::WRL::RuntimeClass<IIterator<HSTRING>>
  35. {
  36. HSTRING *items;
  37. uint32 length;
  38. boolean hasMore;
  39. uint32 currentPosition;
  40. public:
  41. HRESULT RuntimeClassInitialize(HSTRING *items, uint32 length)
  42. {
  43. this->items = items;
  44. this->currentPosition = 0;
  45. this->length = length;
  46. this->hasMore = currentPosition < this->length;
  47. return S_OK;
  48. }
  49. ~HSTRINGIterator()
  50. {
  51. }
  52. // IIterator
  53. IFACEMETHODIMP get_Current(_Out_ HSTRING *current)
  54. {
  55. if (current != nullptr)
  56. {
  57. if (hasMore)
  58. {
  59. return WindowsDuplicateString(items[currentPosition], current);
  60. }
  61. else
  62. {
  63. *current = nullptr;
  64. }
  65. }
  66. return E_BOUNDS;
  67. }
  68. IFACEMETHODIMP get_HasCurrent(_Out_ boolean *hasCurrent)
  69. {
  70. if (hasCurrent != nullptr)
  71. {
  72. *hasCurrent = hasMore;
  73. }
  74. return S_OK;
  75. }
  76. IFACEMETHODIMP MoveNext(_Out_opt_ boolean *hasCurrent) sealed
  77. {
  78. this->currentPosition++;
  79. this->hasMore = this->currentPosition < this->length;
  80. if (hasCurrent != nullptr)
  81. {
  82. *hasCurrent = hasMore;
  83. }
  84. return S_OK;
  85. }
  86. IFACEMETHODIMP GetMany(_In_ unsigned capacity,
  87. _Out_writes_to_(capacity,*actual) HSTRING *value,
  88. _Out_ unsigned *actual)
  89. {
  90. uint count = 0;
  91. while (this->hasMore)
  92. {
  93. if (count == capacity)
  94. {
  95. break;
  96. }
  97. if (value != nullptr)
  98. {
  99. get_Current(value + count);
  100. }
  101. count ++;
  102. this->MoveNext(nullptr);
  103. }
  104. if (actual != nullptr)
  105. {
  106. *actual = count;
  107. }
  108. return S_OK;
  109. }
  110. IFACEMETHOD(GetRuntimeClassName)(_Out_ HSTRING* runtimeName) sealed
  111. {
  112. *runtimeName = nullptr;
  113. HRESULT hr = S_OK;
  114. const char16 *name = _u("Js.HSTRINGIterator");
  115. hr = WindowsCreateString(name, static_cast<UINT32>(wcslen(name)), runtimeName);
  116. return hr;
  117. }
  118. IFACEMETHOD(GetTrustLevel)(_Out_ TrustLevel* trustLvl)
  119. {
  120. *trustLvl = BaseTrust;
  121. return S_OK;
  122. }
  123. IFACEMETHOD(GetIids)(_Out_ ULONG *iidCount, _Outptr_result_buffer_(*iidCount) IID **)
  124. {
  125. iidCount;
  126. return E_NOTIMPL;
  127. }
  128. };
  129. class HSTRINGIterable : public Microsoft::WRL::RuntimeClass<IIterable<HSTRING>>
  130. {
  131. HSTRING *items;
  132. uint32 length;
  133. public:
  134. HRESULT RuntimeClassInitialize(HSTRING *string, uint32 length)
  135. {
  136. this->items = HeapNewNoThrowArray(HSTRING, length);
  137. if (this->items == nullptr)
  138. {
  139. return E_OUTOFMEMORY;
  140. }
  141. for(uint32 i = 0; i < length; i++)
  142. {
  143. this->items[i] = string[i];
  144. }
  145. this->length = length;
  146. return S_OK;
  147. }
  148. ~HSTRINGIterable()
  149. {
  150. if(this->items != nullptr)
  151. {
  152. HeapDeleteArray(this->length, items);
  153. }
  154. }
  155. IFACEMETHODIMP First(_Outptr_result_maybenull_ IIterator<HSTRING> **first)
  156. {
  157. return Microsoft::WRL::MakeAndInitialize<HSTRINGIterator>(first, this->items, this->length);
  158. }
  159. IFACEMETHOD(GetRuntimeClassName)(_Out_ HSTRING* runtimeName) sealed
  160. {
  161. *runtimeName = nullptr;
  162. HRESULT hr = S_OK;
  163. // Return type that does not exist in metadata
  164. const char16 *name = _u("Js.HSTRINGIterable");
  165. hr = WindowsCreateString(name, static_cast<UINT32>(wcslen(name)), runtimeName);
  166. return hr;
  167. }
  168. IFACEMETHOD(GetTrustLevel)(_Out_ TrustLevel* trustLvl)
  169. {
  170. *trustLvl = BaseTrust;
  171. return S_OK;
  172. }
  173. IFACEMETHOD(GetIids)(_Out_ ULONG *iidCount, _Outptr_result_buffer_(*iidCount) IID **)
  174. {
  175. iidCount;
  176. return E_NOTIMPL;
  177. }
  178. };
  179. #endif
  180. inline DelayLoadWindowsGlobalization* WindowsGlobalizationAdapter::GetWindowsGlobalizationLibrary(_In_ ScriptContext* scriptContext)
  181. {
  182. return this->GetWindowsGlobalizationLibrary(scriptContext->GetThreadContext());
  183. }
  184. inline DelayLoadWindowsGlobalization* WindowsGlobalizationAdapter::GetWindowsGlobalizationLibrary(_In_ ThreadContext* threadContext)
  185. {
  186. return threadContext->GetWindowsGlobalizationLibrary();
  187. }
  188. template<typename T>
  189. HRESULT WindowsGlobalizationAdapter::GetActivationFactory(DelayLoadWindowsGlobalization *delayLoadLibrary, LPCWSTR factoryName, T** instance)
  190. {
  191. *instance = nullptr;
  192. AutoCOMPtr<IActivationFactory> factory;
  193. HSTRING hString;
  194. HSTRING_HEADER hStringHdr;
  195. HRESULT hr;
  196. // factoryName will never get truncated as the name of interfaces in Windows.globalization are not that long.
  197. IfFailedReturn(delayLoadLibrary->WindowsCreateStringReference(factoryName, static_cast<UINT32>(wcslen(factoryName)), &hStringHdr, &hString));
  198. AnalysisAssert(hString);
  199. IfFailedReturn(delayLoadLibrary->DllGetActivationFactory(hString, &factory));
  200. return factory->QueryInterface(__uuidof(T), reinterpret_cast<void**>(instance));
  201. }
  202. #ifdef ENABLE_INTL_OBJECT
  203. HRESULT WindowsGlobalizationAdapter::EnsureCommonObjectsInitialized(DelayLoadWindowsGlobalization *library)
  204. {
  205. HRESULT hr = S_OK;
  206. if (initializedCommonGlobObjects)
  207. {
  208. AssertMsg(hrForCommonGlobObjectsInit == S_OK, "If IntlGlobObjects are initialized, we should be returning S_OK.");
  209. return hrForCommonGlobObjectsInit;
  210. }
  211. else if (hrForCommonGlobObjectsInit != S_OK)
  212. {
  213. return hrForCommonGlobObjectsInit;
  214. }
  215. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Globalization_Language, &languageFactory), hrForCommonGlobObjectsInit);
  216. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Globalization_Language, &languageStatics), hrForCommonGlobObjectsInit);
  217. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Globalization_DateTimeFormatting_DateTimeFormatter, &dateTimeFormatterFactory), hrForCommonGlobObjectsInit);
  218. hrForCommonGlobObjectsInit = S_OK;
  219. initializedCommonGlobObjects = true;
  220. return hr;
  221. }
  222. HRESULT WindowsGlobalizationAdapter::EnsureDateTimeFormatObjectsInitialized(DelayLoadWindowsGlobalization *library)
  223. {
  224. HRESULT hr = S_OK;
  225. if (initializedDateTimeFormatObjects)
  226. {
  227. AssertMsg(hrForDateTimeFormatObjectsInit == S_OK, "If DateTimeFormatObjects are initialized, we should be returning S_OK.");
  228. return hrForDateTimeFormatObjectsInit;
  229. }
  230. else if (hrForDateTimeFormatObjectsInit != S_OK)
  231. {
  232. return hrForDateTimeFormatObjectsInit;
  233. }
  234. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Globalization_Calendar, &calendarFactory), hrForDateTimeFormatObjectsInit);
  235. IfFailedSetErrorCodeAndReturn(this->CreateTimeZoneOnCalendar(library, &defaultTimeZoneCalendar), hrForDateTimeFormatObjectsInit);
  236. IfFailedSetErrorCodeAndReturn(this->CreateTimeZoneOnCalendar(library, &timeZoneCalendar), hrForDateTimeFormatObjectsInit);
  237. hrForDateTimeFormatObjectsInit = S_OK;
  238. initializedDateTimeFormatObjects = true;
  239. return hr;
  240. }
  241. HRESULT WindowsGlobalizationAdapter::EnsureNumberFormatObjectsInitialized(DelayLoadWindowsGlobalization *library)
  242. {
  243. HRESULT hr = S_OK;
  244. if (initializedNumberFormatObjects)
  245. {
  246. AssertMsg(hrForNumberFormatObjectsInit == S_OK, "If NumberFormatObjects are initialized, we should be returning S_OK.");
  247. return hrForNumberFormatObjectsInit;
  248. }
  249. else if (hrForNumberFormatObjectsInit != S_OK)
  250. {
  251. return hrForNumberFormatObjectsInit;
  252. }
  253. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Globalization_NumberFormatting_CurrencyFormatter, &currencyFormatterFactory), hrForNumberFormatObjectsInit);
  254. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Globalization_NumberFormatting_DecimalFormatter, &decimalFormatterFactory), hrForNumberFormatObjectsInit);
  255. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Globalization_NumberFormatting_PercentFormatter, &percentFormatterFactory), hrForNumberFormatObjectsInit);
  256. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Globalization_NumberFormatting_SignificantDigitsNumberRounder, &significantDigitsRounderActivationFactory), hrForNumberFormatObjectsInit);
  257. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Globalization_NumberFormatting_IncrementNumberRounder, &incrementNumberRounderActivationFactory), hrForNumberFormatObjectsInit);
  258. hrForNumberFormatObjectsInit = S_OK;
  259. initializedNumberFormatObjects = true;
  260. return hr;
  261. }
  262. #endif
  263. #if ENABLE_UNICODE_API
  264. HRESULT WindowsGlobalizationAdapter::EnsureDataTextObjectsInitialized(DelayLoadWindowsGlobalization *library)
  265. {
  266. HRESULT hr = S_OK;
  267. if (initializedCharClassifierObjects)
  268. {
  269. AssertMsg(hrForCharClassifierObjectsInit == S_OK, "If DataTextObjects are initialized, we should be returning S_OK.");
  270. return hrForCharClassifierObjectsInit;
  271. }
  272. else if (hrForCharClassifierObjectsInit != S_OK)
  273. {
  274. return hrForCharClassifierObjectsInit;
  275. }
  276. IfFailedSetErrorCodeAndReturn(GetActivationFactory(library, RuntimeClass_Windows_Data_Text_UnicodeCharacters, &unicodeStatics), hrForCharClassifierObjectsInit);
  277. hrForCharClassifierObjectsInit = S_OK;
  278. initializedCharClassifierObjects = true;
  279. return hr;
  280. }
  281. #endif
  282. #ifdef ENABLE_INTL_OBJECT
  283. HRESULT WindowsGlobalizationAdapter::CreateLanguage(_In_ ScriptContext* scriptContext, _In_z_ PCWSTR languageTag, ILanguage** language)
  284. {
  285. HRESULT hr = S_OK;
  286. HSTRING hString;
  287. HSTRING_HEADER hStringHdr;
  288. // OK for languageTag to get truncated as it would pass incomplete languageTag below which
  289. // will be rejected by globalization dll
  290. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(languageTag, static_cast<UINT32>(wcslen(languageTag)), &hStringHdr, &hString));
  291. AnalysisAssert(hString);
  292. IfFailedReturn(this->languageFactory->CreateLanguage(hString, language));
  293. return hr;
  294. }
  295. boolean WindowsGlobalizationAdapter::IsWellFormedLanguageTag(_In_ ScriptContext* scriptContext, _In_z_ PCWSTR languageTag)
  296. {
  297. boolean retVal;
  298. HRESULT hr;
  299. HSTRING hString = nullptr;
  300. HSTRING_HEADER hStringHdr;
  301. // OK for languageTag to get truncated as it would pass incomplete languageTag below which
  302. // will be rejected by globalization dll
  303. IfFailThrowHr(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(languageTag, static_cast<UINT32>(wcslen(languageTag)), &hStringHdr, &hString));
  304. if (hString == nullptr)
  305. {
  306. return 0;
  307. }
  308. IfFailThrowHr(this->languageStatics->IsWellFormed(hString, &retVal));
  309. return retVal;
  310. }
  311. HRESULT WindowsGlobalizationAdapter::NormalizeLanguageTag(_In_ ScriptContext* scriptContext, _In_z_ PCWSTR languageTag, HSTRING *result)
  312. {
  313. HRESULT hr;
  314. AutoCOMPtr<ILanguage> language;
  315. IfFailedReturn(CreateLanguage(scriptContext, languageTag, &language));
  316. IfFailedReturn(language->get_LanguageTag(result));
  317. IfNullReturnError(*result, E_FAIL);
  318. return hr;
  319. }
  320. boolean WindowsGlobalizationAdapter::ValidateAndCanonicalizeTimeZone(_In_ ScriptContext* scriptContext, _In_z_ PCWSTR timeZoneId, HSTRING *result)
  321. {
  322. HRESULT hr = S_OK;
  323. HSTRING timeZone;
  324. HSTRING_HEADER timeZoneHeader;
  325. // Construct HSTRING of timeZoneId passed
  326. // OK for timeZoneId to get truncated as it would pass incomplete timeZoneId below which
  327. // will be rejected by globalization dll
  328. IfFailThrowHr(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(timeZoneId, static_cast<UINT32>(wcslen(timeZoneId)), &timeZoneHeader, &timeZone));
  329. // The warning is timeZone could be '0'. This is valid scenario and in that case, ChangeTimeZone() would
  330. // return error HR in which case we will throw.
  331. #pragma warning(suppress:6387)
  332. // ChangeTimeZone should fail if this is not a valid time zone
  333. hr = timeZoneCalendar->ChangeTimeZone(timeZone);
  334. if (hr != S_OK)
  335. {
  336. return false;
  337. }
  338. // Retrieve canonicalize timeZone name
  339. IfFailThrowHr(timeZoneCalendar->GetTimeZone(result));
  340. if (*result == nullptr)
  341. {
  342. return false;
  343. }
  344. return true;
  345. }
  346. HRESULT WindowsGlobalizationAdapter::GetDefaultTimeZoneId(_In_ ScriptContext* scriptContext, HSTRING *result)
  347. {
  348. HRESULT hr = S_OK;
  349. IfFailThrowHr(defaultTimeZoneCalendar->GetTimeZone(result));
  350. IfNullReturnError(*result, E_FAIL);
  351. return hr;
  352. }
  353. HRESULT WindowsGlobalizationAdapter::CreateTimeZoneOnCalendar(_In_ DelayLoadWindowsGlobalization *library, __out::ITimeZoneOnCalendar** result)
  354. {
  355. AutoCOMPtr<::ICalendar> calendar;
  356. HRESULT hr = S_OK;
  357. // initialize hard-coded default languages
  358. AutoArrayPtr<HSTRING> arr(HeapNewArray(HSTRING, 1), 1);
  359. AutoArrayPtr<HSTRING_HEADER> headers(HeapNewArray(HSTRING_HEADER, 1), 1);
  360. IfFailedReturn(library->WindowsCreateStringReference(_u("en-US"), static_cast<UINT32>(wcslen(_u("en-US"))), (headers), (arr)));
  361. Microsoft::WRL::ComPtr<IIterable<HSTRING>> defaultLanguages;
  362. IfFailedReturn(Microsoft::WRL::MakeAndInitialize<HSTRINGIterable>(&defaultLanguages, arr, 1));
  363. // Create calendar object
  364. IfFailedReturn(this->calendarFactory->CreateCalendarDefaultCalendarAndClock(defaultLanguages.Get(), &calendar));
  365. // Get ITimeZoneOnCalendar part of calendar object
  366. IfFailedReturn(calendar->QueryInterface(__uuidof(::ITimeZoneOnCalendar), reinterpret_cast<void**>(result)));
  367. return hr;
  368. }
  369. #define DetachAndReleaseFactoryObjects(object) \
  370. if (this->object) \
  371. { \
  372. this->object.Detach()->Release(); \
  373. }
  374. void WindowsGlobalizationAdapter::ResetCommonFactoryObjects()
  375. {
  376. // Reset only if its not initialized completely.
  377. if (!this->initializedCommonGlobObjects)
  378. {
  379. this->hrForCommonGlobObjectsInit = S_OK;
  380. DetachAndReleaseFactoryObjects(languageFactory);
  381. DetachAndReleaseFactoryObjects(languageStatics);
  382. DetachAndReleaseFactoryObjects(dateTimeFormatterFactory);
  383. }
  384. }
  385. void WindowsGlobalizationAdapter::ResetDateTimeFormatFactoryObjects()
  386. {
  387. // Reset only if its not initialized completely.
  388. if (!this->initializedDateTimeFormatObjects)
  389. {
  390. this->hrForDateTimeFormatObjectsInit = S_OK;
  391. DetachAndReleaseFactoryObjects(calendarFactory);
  392. DetachAndReleaseFactoryObjects(timeZoneCalendar);
  393. DetachAndReleaseFactoryObjects(defaultTimeZoneCalendar);
  394. }
  395. }
  396. void WindowsGlobalizationAdapter::ResetNumberFormatFactoryObjects()
  397. {
  398. // Reset only if its not initialized completely.
  399. if (!this->initializedNumberFormatObjects)
  400. {
  401. this->hrForNumberFormatObjectsInit = S_OK;
  402. DetachAndReleaseFactoryObjects(currencyFormatterFactory);
  403. DetachAndReleaseFactoryObjects(decimalFormatterFactory);
  404. DetachAndReleaseFactoryObjects(percentFormatterFactory);
  405. DetachAndReleaseFactoryObjects(incrementNumberRounderActivationFactory);
  406. DetachAndReleaseFactoryObjects(significantDigitsRounderActivationFactory);
  407. }
  408. }
  409. #undef DetachAndReleaseFactoryObjects
  410. HRESULT WindowsGlobalizationAdapter::CreateCurrencyFormatterCode(_In_ ScriptContext* scriptContext, _In_z_ PCWSTR currencyCode, NumberFormatting::ICurrencyFormatter** currencyFormatter)
  411. {
  412. HRESULT hr;
  413. HSTRING hString;
  414. HSTRING_HEADER hStringHdr;
  415. // OK for currencyCode to get truncated as it would pass incomplete currencyCode below which
  416. // will be rejected by globalization dll
  417. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(currencyCode, static_cast<UINT32>(wcslen(currencyCode)), &hStringHdr, &hString));
  418. AnalysisAssert(hString);
  419. IfFailedReturn(this->currencyFormatterFactory->CreateCurrencyFormatterCode(hString, currencyFormatter));
  420. return hr;
  421. }
  422. HRESULT WindowsGlobalizationAdapter::CreateCurrencyFormatter(_In_ ScriptContext* scriptContext, PCWSTR* localeStrings, uint32 numLocaleStrings, _In_z_ PCWSTR currencyCode, NumberFormatting::ICurrencyFormatter** currencyFormatter)
  423. {
  424. HRESULT hr;
  425. HSTRING hString;
  426. HSTRING_HEADER hStringHdr;
  427. AutoArrayPtr<HSTRING> arr(HeapNewArray(HSTRING, numLocaleStrings), numLocaleStrings);
  428. AutoArrayPtr<HSTRING_HEADER> headers(HeapNewArray(HSTRING_HEADER, numLocaleStrings), numLocaleStrings);
  429. for(uint32 i = 0; i< numLocaleStrings; i++)
  430. {
  431. // OK for localeString to get truncated as it would pass incomplete localeString below which
  432. // will be rejected by globalization dll.
  433. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(localeStrings[i], static_cast<UINT32>(wcslen(localeStrings[i])), (headers + i), (arr + i)));
  434. }
  435. Microsoft::WRL::ComPtr<IIterable<HSTRING>> languages(nullptr);
  436. IfFailedReturn(Microsoft::WRL::MakeAndInitialize<HSTRINGIterable>(&languages, arr, numLocaleStrings));
  437. HSTRING geoString;
  438. HSTRING_HEADER geoStringHeader;
  439. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(_u("ZZ"), 2, &geoStringHeader, &geoString));
  440. AnalysisAssert(geoString);
  441. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(currencyCode, static_cast<UINT32>(wcslen(currencyCode)), &hStringHdr, &hString));
  442. AnalysisAssert(hString);
  443. IfFailedReturn(this->currencyFormatterFactory->CreateCurrencyFormatterCodeContext(hString, languages.Get(), geoString, currencyFormatter));
  444. return hr;
  445. }
  446. HRESULT WindowsGlobalizationAdapter::CreateNumberFormatter(_In_ ScriptContext* scriptContext, PCWSTR* localeStrings, uint32 numLocaleStrings, NumberFormatting::INumberFormatter** numberFormatter)
  447. {
  448. HRESULT hr = S_OK;
  449. AutoArrayPtr<HSTRING> arr(HeapNewArray(HSTRING, numLocaleStrings), numLocaleStrings);
  450. AutoArrayPtr<HSTRING_HEADER> headers(HeapNewArray(HSTRING_HEADER, numLocaleStrings), numLocaleStrings);
  451. for(uint32 i = 0; i< numLocaleStrings; i++)
  452. {
  453. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(localeStrings[i], static_cast<UINT32>(wcslen(localeStrings[i])), (headers + i), (arr + i)));
  454. }
  455. Microsoft::WRL::ComPtr<IIterable<HSTRING>> languages(nullptr);
  456. IfFailedReturn(Microsoft::WRL::MakeAndInitialize<HSTRINGIterable>(&languages, arr, numLocaleStrings));
  457. HSTRING geoString;
  458. HSTRING_HEADER geoStringHeader;
  459. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(_u("ZZ"), 2, &geoStringHeader, &geoString));
  460. AnalysisAssert(geoString);
  461. IfFailedReturn(this->decimalFormatterFactory->CreateDecimalFormatter(languages.Get(), geoString, numberFormatter));
  462. return hr;
  463. }
  464. HRESULT WindowsGlobalizationAdapter::CreatePercentFormatter(_In_ ScriptContext* scriptContext, PCWSTR* localeStrings, uint32 numLocaleStrings, NumberFormatting::INumberFormatter** numberFormatter)
  465. {
  466. HRESULT hr = S_OK;
  467. AutoArrayPtr<HSTRING> arr(HeapNewArray(HSTRING, numLocaleStrings), numLocaleStrings);
  468. AutoArrayPtr<HSTRING_HEADER> headers(HeapNewArray(HSTRING_HEADER, numLocaleStrings), numLocaleStrings);
  469. for(uint32 i = 0; i< numLocaleStrings; i++)
  470. {
  471. // OK for localeString to get truncated as it would pass incomplete localeString below which
  472. // will be rejected by globalization dll.
  473. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(localeStrings[i], static_cast<UINT32>(wcslen(localeStrings[i])), (headers + i), (arr + i)));
  474. }
  475. Microsoft::WRL::ComPtr<IIterable<HSTRING>> languages(nullptr);
  476. IfFailedReturn(Microsoft::WRL::MakeAndInitialize<HSTRINGIterable>(&languages, arr, numLocaleStrings));
  477. HSTRING geoString;
  478. HSTRING_HEADER geoStringHeader;
  479. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(_u("ZZ"), 2, &geoStringHeader, &geoString));
  480. AnalysisAssert(geoString);
  481. IfFailedReturn(this->percentFormatterFactory->CreatePercentFormatter(languages.Get(), geoString, numberFormatter));
  482. return hr;
  483. }
  484. HRESULT WindowsGlobalizationAdapter::CreateDateTimeFormatter(_In_ ScriptContext* scriptContext, _In_z_ PCWSTR formatString, _In_z_ PCWSTR* localeStrings,
  485. uint32 numLocaleStrings, _In_opt_z_ PCWSTR calendar, _In_opt_z_ PCWSTR clock, _Out_ DateTimeFormatting::IDateTimeFormatter** result)
  486. {
  487. HRESULT hr = S_OK;
  488. if(numLocaleStrings == 0) return E_INVALIDARG;
  489. AnalysisAssert((calendar == nullptr && clock == nullptr) || (calendar != nullptr && clock != nullptr));
  490. HSTRING fsHString;
  491. HSTRING_HEADER fsHStringHdr;
  492. // OK for formatString to get truncated as it would pass incomplete formatString below which
  493. // will be rejected by globalization dll.
  494. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(formatString, static_cast<UINT32>(wcslen(formatString)), &fsHStringHdr, &fsHString));
  495. AnalysisAssert(fsHString);
  496. AutoArrayPtr<HSTRING> arr(HeapNewArray(HSTRING, numLocaleStrings), numLocaleStrings);
  497. AutoArrayPtr<HSTRING_HEADER> headers(HeapNewArray(HSTRING_HEADER, numLocaleStrings), numLocaleStrings);
  498. for(uint32 i = 0; i< numLocaleStrings; i++)
  499. {
  500. // OK for localeString to get truncated as it would pass incomplete localeString below which
  501. // will be rejected by globalization dll.
  502. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(localeStrings[i], static_cast<UINT32>(wcslen(localeStrings[i])), (headers + i), (arr + i)));
  503. }
  504. Microsoft::WRL::ComPtr<IIterable<HSTRING>> languages(nullptr);
  505. IfFailedReturn(Microsoft::WRL::MakeAndInitialize<HSTRINGIterable>(&languages, arr, numLocaleStrings));
  506. if(clock == nullptr)
  507. {
  508. IfFailedReturn(this->dateTimeFormatterFactory->CreateDateTimeFormatterLanguages(fsHString, languages.Get(), result));
  509. }
  510. else
  511. {
  512. HSTRING geoString;
  513. HSTRING_HEADER geoStringHeader;
  514. HSTRING calString;
  515. HSTRING_HEADER calStringHeader;
  516. HSTRING clockString;
  517. HSTRING_HEADER clockStringHeader;
  518. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(_u("ZZ"), 2, &geoStringHeader, &geoString));
  519. AnalysisAssert(geoString);
  520. // OK for calendar/clock to get truncated as it would pass incomplete text below which
  521. // will be rejected by globalization dll.
  522. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(calendar, static_cast<UINT32>(wcslen(calendar)), &calStringHeader, &calString));
  523. AnalysisAssert(calString);
  524. IfFailedReturn(GetWindowsGlobalizationLibrary(scriptContext)->WindowsCreateStringReference(clock, static_cast<UINT32>(wcslen(clock)), &clockStringHeader, &clockString));
  525. AnalysisAssert(clockString);
  526. IfFailedReturn(this->dateTimeFormatterFactory->CreateDateTimeFormatterContext(fsHString, languages.Get(), geoString, calString, clockString, result));
  527. }
  528. return hr;
  529. }
  530. HRESULT WindowsGlobalizationAdapter::CreateIncrementNumberRounder(_In_ ScriptContext* scriptContext, NumberFormatting::INumberRounder** numberRounder)
  531. {
  532. return incrementNumberRounderActivationFactory->ActivateInstance(reinterpret_cast<IInspectable**>(numberRounder));
  533. }
  534. HRESULT WindowsGlobalizationAdapter::CreateSignificantDigitsRounder(_In_ ScriptContext* scriptContext, NumberFormatting::INumberRounder** numberRounder)
  535. {
  536. return significantDigitsRounderActivationFactory->ActivateInstance(reinterpret_cast<IInspectable**>(numberRounder));
  537. }
  538. HRESULT WindowsGlobalizationAdapter::GetResolvedLanguage(_In_ DateTimeFormatting::IDateTimeFormatter* formatter, HSTRING * locale)
  539. {
  540. HRESULT hr = formatter->get_ResolvedLanguage(locale);
  541. return VerifyResult(locale, hr);
  542. }
  543. HRESULT WindowsGlobalizationAdapter::GetResolvedLanguage(_In_ NumberFormatting::INumberFormatterOptions* formatter, HSTRING * locale)
  544. {
  545. HRESULT hr = formatter->get_ResolvedLanguage(locale);
  546. return VerifyResult(locale, hr);
  547. }
  548. HRESULT WindowsGlobalizationAdapter::GetNumeralSystem(_In_ NumberFormatting::INumberFormatterOptions* formatter, HSTRING * hNumeralSystem)
  549. {
  550. HRESULT hr = formatter->get_NumeralSystem(hNumeralSystem);
  551. return VerifyResult(hNumeralSystem, hr);
  552. }
  553. HRESULT WindowsGlobalizationAdapter::GetNumeralSystem(_In_ DateTimeFormatting::IDateTimeFormatter* formatter, HSTRING * hNumeralSystem)
  554. {
  555. HRESULT hr = formatter->get_NumeralSystem(hNumeralSystem);
  556. return VerifyResult(hNumeralSystem, hr);
  557. }
  558. HRESULT WindowsGlobalizationAdapter::GetCalendar(_In_ DateTimeFormatting::IDateTimeFormatter* formatter, HSTRING * hCalendar)
  559. {
  560. HRESULT hr = formatter->get_Calendar(hCalendar);
  561. return VerifyResult(hCalendar, hr);
  562. }
  563. HRESULT WindowsGlobalizationAdapter::GetClock(_In_ DateTimeFormatting::IDateTimeFormatter* formatter, HSTRING * hClock)
  564. {
  565. HRESULT hr = formatter->get_Clock(hClock);
  566. return VerifyResult(hClock, hr);
  567. }
  568. HRESULT WindowsGlobalizationAdapter::GetItemAt(_In_ IVectorView<HSTRING>* vector, _In_ uint32 index, HSTRING * item)
  569. {
  570. HRESULT hr = vector->GetAt(index, item);
  571. return VerifyResult(item, hr);
  572. }
  573. /* static */
  574. HRESULT WindowsGlobalizationAdapter::VerifyResult(HSTRING * result, HRESULT errCode)
  575. {
  576. HRESULT hr = S_OK;
  577. IfFailedReturn(errCode);
  578. IfNullReturnError(*result, E_FAIL);
  579. return hr;
  580. }
  581. #endif
  582. #endif // INTL_WINGLOB
  583. } // namespace Js
  584. #endif // defined(ENABLE_INTL_OBJECT) || defined(ENABLE_ES6_CHAR_CLASSIFIER)