Skip to content

Commit 4f7b50c

Browse files
committed
Implement JavascriptArray::GetLocaleSeparator for Linux/macOS. Refactor JavascriptArray::GetLocaleSeparator into new module PlatformAgnostic::Arrays
1 parent 5775ba1 commit 4f7b50c

File tree

8 files changed

+172
-36
lines changed

8 files changed

+172
-36
lines changed

lib/Common/CommonPal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ namespace PlatformAgnostic
744744

745745
#include "PlatformAgnostic/DateTime.h"
746746
#include "PlatformAgnostic/Numbers.h"
747+
#include "PlatformAgnostic/Arrays.h"
747748
#include "PlatformAgnostic/SystemInfo.h"
748749
#include "PlatformAgnostic/Thread.h"
749750
#include "PlatformAgnostic/AssemblyCommon.h"

lib/Common/PlatformAgnostic/Arrays.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
#pragma once
6+
7+
namespace PlatformAgnostic
8+
{
9+
namespace Arrays
10+
{
11+
#ifndef ENABLE_GLOBALIZATION
12+
13+
class ArrayLocalization
14+
{
15+
char16 localeSeparator;
16+
17+
static const uint16 BufSize = 256;
18+
19+
public:
20+
21+
ArrayLocalization();
22+
23+
inline char16 GetLocaleSeparator() { return localeSeparator; }
24+
};
25+
26+
#endif
27+
28+
static const uint32 SeparatorBufferSize = 6;
29+
30+
// According to MSDN the maximum number of characters for the list separator (LOCALE_SLIST) is four, including a terminating null character.
31+
bool GetLocaleSeparator(char16* szSeparator, uint32* sepOutLength, uint32 sepBufferSize);
32+
33+
template <uint32 sepBufferSize>
34+
inline bool GetLocaleSeparator(char16(&szSepatator)[sepBufferSize], uint32 *sepOutLength)
35+
{
36+
return GetLocaleSeparator(szSeparator, sepOutLength, sepBufferSize);
37+
}
38+
39+
} // namespace Arrays
40+
} // namespace PlatformAgnostic

lib/Runtime/Library/JavascriptArray.cpp

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8152,37 +8152,6 @@ namespace Js
81528152
}
81538153
#endif
81548154

8155-
JavascriptString* JavascriptArray::GetLocaleSeparator(ScriptContext* scriptContext)
8156-
{
8157-
#ifdef ENABLE_GLOBALIZATION
8158-
LCID lcid = GetUserDefaultLCID();
8159-
int count = 0;
8160-
char16 szSeparator[6];
8161-
8162-
// According to the document for GetLocaleInfo this is a sufficient buffer size.
8163-
count = GetLocaleInfoW(lcid, LOCALE_SLIST, szSeparator, 5);
8164-
if( !count)
8165-
{
8166-
AssertMsg(FALSE, "GetLocaleInfo failed");
8167-
return scriptContext->GetLibrary()->GetCommaSpaceDisplayString();
8168-
}
8169-
else
8170-
{
8171-
// Append ' ' if necessary
8172-
if( count < 2 || szSeparator[count-2] != ' ')
8173-
{
8174-
szSeparator[count-1] = ' ';
8175-
szSeparator[count] = '\0';
8176-
}
8177-
8178-
return JavascriptString::NewCopyBuffer(szSeparator, count, scriptContext);
8179-
}
8180-
#else
8181-
// xplat-todo: Support locale-specific separator
8182-
return scriptContext->GetLibrary()->GetCommaSpaceDisplayString();
8183-
#endif
8184-
}
8185-
81868155
template <typename T>
81878156
JavascriptString* JavascriptArray::ToLocaleString(T* arr, ScriptContext* scriptContext)
81888157
{
@@ -8224,7 +8193,21 @@ namespace Js
82248193

82258194
if (length > 1)
82268195
{
8227-
JavascriptString* separator = GetLocaleSeparator(scriptContext);
8196+
uint32 sepSize = 0;
8197+
char16 szSeparator[Arrays::SeparatorBufferSize];
8198+
8199+
bool hasLocaleSeparator = Arrays::GetLocaleSeparator(szSeparator, &sepSize, Arrays::SeparatorBufferSize);
8200+
8201+
JavascriptString* separator = nullptr;
8202+
8203+
if (hasLocaleSeparator)
8204+
{
8205+
separator = JavascriptString::NewCopyBuffer(szSeparator, static_cast<charcount_t>(sepSize), scriptContext);
8206+
}
8207+
else
8208+
{
8209+
separator = scriptContext->GetLibrary()->GetCommaSpaceDisplayString();
8210+
}
82288211

82298212
for (uint32 i = 1; i < length; i++)
82308213
{

lib/Runtime/Library/JavascriptArray.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,6 @@ namespace Js
892892

893893
template <typename T>
894894
static JavascriptString* ToLocaleString(T* obj, ScriptContext* scriptContext);
895-
static JavascriptString* GetLocaleSeparator(ScriptContext* scriptContext);
896895

897896
public:
898897
static uint32 GetOffsetOfArrayFlags() { return offsetof(JavascriptArray, arrayFlags); }

lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Condition="'$(ChakraBuildPathImported)'!='true'" Project="$(SolutionDir)Chakra.Build.Paths.props" />
44
<Import Project="$(BuildConfigPropsPath)Chakra.Build.ProjectConfiguration.props" />
@@ -44,8 +44,9 @@
4444
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\DateTime.cpp" />
4545
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\DaylightHelper.cpp" />
4646
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\HiResTimer.cpp" />
47-
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\UnicodeText.cpp"/>
47+
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\UnicodeText.cpp" />
4848
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\NumbersUtility.cpp" />
49+
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\ArraysUtility.cpp" />
4950
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\SystemInfo.cpp" />
5051
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\Thread.cpp" />
5152
<ClCompile Include="$(MSBuildThisFileDirectory)Platform\Windows\PerfTrace.cpp" />
@@ -67,4 +68,4 @@
6768
</ItemGroup>
6869
<Import Project="$(BuildConfigPropsPath)Chakra.Build.targets" Condition="exists('$(BuildConfigPropsPath)Chakra.Build.targets')" />
6970
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
70-
</Project>
71+
</Project>

lib/Runtime/PlatformAgnostic/Platform/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set(PL_SOURCE_FILES
55
Common/HiResTimer.cpp
66
Common/DateTime.cpp
77
Linux/NumbersUtility.cpp
8+
POSIX/ArraysUtility.cpp
89
Common/Thread.cpp
910
Common/Trace.cpp
1011
Common/SystemInfo.Common.cpp
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
6+
#include "Common.h"
7+
#include "ChakraPlatform.h"
8+
#include <locale.h>
9+
10+
namespace PlatformAgnostic
11+
{
12+
namespace Arrays
13+
{
14+
15+
static char16 commaSeparator = _u(',');
16+
static char16 semicolonSeparator = _u(';');
17+
18+
ArrayLocalization::ArrayLocalization()
19+
{
20+
char buffer[BufSize];
21+
char *old_locale = setlocale(LC_NUMERIC, NULL);
22+
23+
if (old_locale != NULL)
24+
{
25+
memcpy(buffer, old_locale, BufSize);
26+
27+
setlocale(LC_NUMERIC, "");
28+
}
29+
30+
struct lconv *locale_format = localeconv();
31+
if (locale_format != NULL)
32+
{
33+
// No specific list separator on Linux/macOS
34+
// Use this pattern to determine the list separator
35+
if (*locale_format->decimal_point == commaSeparator)
36+
{
37+
localeSeparator = semicolonSeparator;
38+
}
39+
else
40+
{
41+
localeSeparator = commaSeparator;
42+
}
43+
}
44+
45+
if (old_locale != NULL)
46+
{
47+
setlocale(LC_NUMERIC, buffer);
48+
}
49+
}
50+
51+
bool GetLocaleSeparator(char16* szSeparator, uint32* sepOutSize, uint32 sepBufSize)
52+
{
53+
ArrayLocalization arrayLocalization;
54+
//Append ' ' after separator
55+
szSeparator[*sepOutSize] = arrayLocalization.GetLocaleSeparator();
56+
szSeparator[++(*sepOutSize)] = ' ';
57+
szSeparator[++(*sepOutSize)] = '\0';
58+
59+
return true;
60+
}
61+
62+
} // namespace Arrays
63+
} // namespace PlatformAgnostic
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
6+
#include "RuntimePlatformAgnosticPch.h"
7+
#include "Common.h"
8+
#include "ChakraPlatform.h"
9+
10+
namespace PlatformAgnostic
11+
{
12+
namespace Arrays
13+
{
14+
// Potential candidate for optimization
15+
bool GetLocaleSeparator(char16* szSeparator, uint32* sepOutSize, uint32 sepBufSize)
16+
{
17+
char16 localeName[LOCALE_NAME_MAX_LENGTH] = { 0 };
18+
19+
int ret = GetUserDefaultLocaleName(localeName, _countof(localeName));
20+
21+
if (ret == 0)
22+
{
23+
AssertMsg(FALSE, "GetUserDefaultLocaleName failed");
24+
return false;
25+
}
26+
27+
*sepOutSize = GetLocaleInfoEx(localeName, LOCALE_SLIST, szSeparator, sepBufSize);
28+
29+
if (*sepOutSize == 0)
30+
{
31+
AssertMsg(FALSE, "GetLocaleInfo failed");
32+
return false;
33+
}
34+
else
35+
{
36+
// Append ' ' if necessary
37+
if (*sepOutSize < 2 || szSeparator[*sepOutSize - 2] != ' ')
38+
{
39+
szSeparator[*sepOutSize - 1] = ' ';
40+
szSeparator[*sepOutSize] = '\0';
41+
}
42+
}
43+
44+
return true;
45+
}
46+
47+
} // namespace Arrays
48+
} // namespace PlatformAgnostic

0 commit comments

Comments
 (0)