Get sort version dynamically and expose ICU version from native component (#13382)
authorTarek Mahmoud Sayed <tarekms@microsoft.com>
Wed, 16 Aug 2017 01:49:16 +0000 (18:49 -0700)
committerGitHub <noreply@github.com>
Wed, 16 Aug 2017 01:49:16 +0000 (18:49 -0700)
* Support ICU Version

* Add the assert

src/corefx/System.Globalization.Native/collation.cpp
src/corefx/System.Globalization.Native/icushim.cpp
src/corefx/System.Globalization.Native/icushim.h
src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs

index a8c24e1..3aefae2 100644 (file)
@@ -327,12 +327,6 @@ bool CanIgnoreAllCollationElements(const UCollator* pColl, const UChar* lpStr, i
 
 }
 
-extern "C" int32_t GlobalizationNative_GetSortVersion()
-{
-    // we didn't use UCOL_TAILORINGS_VERSION because it is deprecated in ICU v5
-    return UCOL_RUNTIME_VERSION << 16 | UCOL_BUILDER_VERSION;
-}
-
 extern "C" ResultCode GlobalizationNative_GetSortHandle(const char* lpLocaleName, SortHandle** ppSortHandle)
 {
     assert(ppSortHandle != nullptr);
@@ -407,6 +401,26 @@ const UCollator* GetCollatorFromSortHandle(SortHandle* pSortHandle, int32_t opti
     return pCollator;
 }
 
+extern "C" int32_t GlobalizationNative_GetSortVersion(SortHandle* pSortHandle)
+{
+    UErrorCode err = U_ZERO_ERROR;
+    const UCollator* pColl = GetCollatorFromSortHandle(pSortHandle, 0, &err);
+    int32_t result = 0;
+
+    if (U_SUCCESS(err))
+    {
+        ucol_getVersion(pColl, (uint8_t *) &result);
+    }
+    else
+    {
+        assert(false && "Unexpected ucol_getVersion to fail.");
+
+        // we didn't use UCOL_TAILORINGS_VERSION because it is deprecated in ICU v5
+        result = UCOL_RUNTIME_VERSION << 16 | UCOL_BUILDER_VERSION;
+    }
+    return result;
+}
+
 /*
 Function:
 CompareString
index 6e7817e..e97896a 100644 (file)
@@ -270,6 +270,15 @@ extern "C" int32_t GlobalizationNative_LoadICU()
     return 1;
 }
 
+// GlobalizationNative_GetICUVersion
+// return the current loaded ICU version
+extern "C" int32_t GlobalizationNative_GetICUVersion()
+{
+    int32_t version;
+    u_getVersion((uint8_t *) &version);
+    return version; 
+}
+
 __attribute__((destructor))
 void ShutdownICUShim()
 {
index 313002e..d7ec2fb 100644 (file)
@@ -38,6 +38,7 @@
 // List of all functions from the ICU libraries that are used in the System.Globalization.Native.so
 #define FOR_ALL_UNCONDITIONAL_ICU_FUNCTIONS \
     PER_FUNCTION_BLOCK(u_charsToUChars, libicuuc) \
+    PER_FUNCTION_BLOCK(u_getVersion, libicuuc) \
     PER_FUNCTION_BLOCK(u_strlen, libicuuc) \
     PER_FUNCTION_BLOCK(u_strncpy, libicuuc) \
     PER_FUNCTION_BLOCK(u_tolower, libicuuc) \
@@ -56,6 +57,7 @@
     PER_FUNCTION_BLOCK(ucol_getRules, libicui18n) \
     PER_FUNCTION_BLOCK(ucol_getSortKey, libicui18n) \
     PER_FUNCTION_BLOCK(ucol_getStrength, libicui18n) \
+    PER_FUNCTION_BLOCK(ucol_getVersion, libicui18n) \
     PER_FUNCTION_BLOCK(ucol_next, libicui18n) \
     PER_FUNCTION_BLOCK(ucol_open, libicui18n) \
     PER_FUNCTION_BLOCK(ucol_openElements, libicui18n) \
@@ -143,6 +145,7 @@ FOR_ALL_ICU_FUNCTIONS
 // Redefine all calls to ICU functions as calls through pointers that are set
 // to the functions of the selected version of ICU in the initialization.
 #define u_charsToUChars(...) u_charsToUChars_ptr(__VA_ARGS__)
+#define u_getVersion(...) u_getVersion_ptr(__VA_ARGS__)
 #define u_strlen(...) u_strlen_ptr(__VA_ARGS__)
 #define u_strncpy(...) u_strncpy_ptr(__VA_ARGS__)
 #define u_tolower(...) u_tolower_ptr(__VA_ARGS__)
@@ -161,6 +164,7 @@ FOR_ALL_ICU_FUNCTIONS
 #define ucol_getRules(...) ucol_getRules_ptr(__VA_ARGS__)
 #define ucol_getSortKey(...) ucol_getSortKey_ptr(__VA_ARGS__)
 #define ucol_getStrength(...) ucol_getStrength_ptr(__VA_ARGS__)
+#define ucol_getVersion(...) ucol_getVersion_ptr(__VA_ARGS__)
 #define ucol_next(...) ucol_next_ptr(__VA_ARGS__)
 #define ucol_open(...) ucol_open_ptr(__VA_ARGS__)
 #define ucol_openElements(...) ucol_openElements_ptr(__VA_ARGS__)
index 79aedd7..683845d 100644 (file)
@@ -44,7 +44,7 @@ internal static partial class Interop
         internal unsafe static extern int CompareStringOrdinalIgnoreCase(char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len);
 
         [DllImport(Libraries.GlobalizationInterop, EntryPoint = "GlobalizationNative_GetSortVersion")]
-        internal static extern int GetSortVersion();
+        internal static extern int GetSortVersion(SafeSortHandle sortHandle);
 
         internal class SafeSortHandle : SafeHandle
         {
index edc9a7f..e58a78e 100644 (file)
@@ -428,7 +428,7 @@ namespace System.Globalization
         {
             Debug.Assert(!_invariantMode);
 
-            int sortVersion = Interop.GlobalizationInterop.GetSortVersion();
+            int sortVersion = Interop.GlobalizationInterop.GetSortVersion(_sortHandle);
             return new SortVersion(sortVersion, LCID, new Guid(sortVersion, 0, 0, 0, 0, 0, 0,
                                                              (byte) (LCID >> 24),
                                                              (byte) ((LCID  & 0x00FF0000) >> 16),