to_wide_string: on Windows get string UTF8 validity and size in a single pass with API 66/18266/2
Simon Marchetto [Mon, 20 Jun 2016 13:55:36 +0000 (15:55 +0200)]
Change-Id: If44e915bac6ef0c5181ed0f11ea3d19208789bc9

scilab/modules/localization/src/c/charEncoding.c
scilab/modules/string/tests/benchmarks/bench_ascii_UTF8.tst [new file with mode: 0644]
scilab/modules/string/tests/unit_tests/ascii.dia.ref
scilab/modules/string/tests/unit_tests/ascii.tst

index 24c0f31..bb4d845 100644 (file)
@@ -66,23 +66,26 @@ wchar_t *to_wide_string(const char *_UTFStr)
 {
     int nwide = 0;
     wchar_t *_buf = NULL;
-    DWORD dwFlags = 0;
-    UINT codePage = CP_ACP;
+    UINT codePage = CP_UTF8;
 
     if (_UTFStr == NULL)
     {
         return NULL;
     }
 
-    if (IsValidUTF8(_UTFStr))
-    {
-        codePage = CP_UTF8;
-    }
-
-    nwide = MultiByteToWideChar(codePage, dwFlags, _UTFStr, -1, NULL, 0);
+    nwide = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, _UTFStr, -1, NULL, 0);
     if (nwide == 0)
     {
-        return NULL;
+        if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION)
+        {
+            codePage = CP_ACP;
+            nwide = MultiByteToWideChar(codePage, 0, _UTFStr, -1, NULL, 0);
+        }
+
+        if (nwide == 0)
+        {
+            return NULL;
+        }
     }
 
     _buf = (wchar_t *)MALLOC(nwide * sizeof(wchar_t));
@@ -91,7 +94,7 @@ wchar_t *to_wide_string(const char *_UTFStr)
         return NULL;
     }
 
-    if (MultiByteToWideChar(codePage, dwFlags, _UTFStr, -1, _buf, nwide) == 0)
+    if (MultiByteToWideChar(codePage, 0, _UTFStr, -1, _buf, nwide) == 0)
     {
         FREE(_buf);
         _buf = NULL;
diff --git a/scilab/modules/string/tests/benchmarks/bench_ascii_UTF8.tst b/scilab/modules/string/tests/benchmarks/bench_ascii_UTF8.tst
new file mode 100644 (file)
index 0000000..430431b
--- /dev/null
@@ -0,0 +1,18 @@
+// ================================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2016 - Scilab Enterprises
+//
+//  This file is distributed under the same license as the Scilab package.
+// ================================================================================
+
+//=================================================================================
+// Benchmark for mgetl function
+//==============================================================================
+
+// <-- BENCH NB RUN : 10 -->
+// column vector composed of 5000 '€' code points
+m = repmat([226 130 172], 1, 50000);
+
+// <-- BENCH START -->
+s = ascii(m);
+// <-- BENCH END -->
index 5cacbb7..5e33af9 100644 (file)
@@ -229,3 +229,11 @@ if or( ascii(A) <> ascii(int32(A)) ) then bugmes();quit;end
 if or( ascii(A) <> ascii(uint8(A)) )  then bugmes();quit;end
 if or( ascii(A) <> ascii(uint16(A)) ) then bugmes();quit;end
 if or( ascii(A) <> ascii(uint32(A)) ) then bugmes();quit;end
+// valid UTF8
+assert_checkequal(ascii("é"), [195 169]);
+assert_checkequal(ascii([195 169]), "é");
+assert_checkequal(ascii("€"), [226 130 172]);
+assert_checkequal(ascii([226 130 172]), "€");
+// invalid UTF8
+assert_checkequal(length(ascii([190 169])), 2);
+assert_checkequal(length(ascii([223 130 172])), 3);
index 41c1584..5bed8ec 100644 (file)
@@ -249,3 +249,13 @@ if or( ascii(A) <> ascii(int32(A)) ) then pause, end
 if or( ascii(A) <> ascii(uint8(A)) )  then pause, end
 if or( ascii(A) <> ascii(uint16(A)) ) then pause, end
 if or( ascii(A) <> ascii(uint32(A)) ) then pause, end
+
+// valid UTF8
+assert_checkequal(ascii("é"), [195 169]);
+assert_checkequal(ascii([195 169]), "é");
+assert_checkequal(ascii("€"), [226 130 172]);
+assert_checkequal(ascii([226 130 172]), "€");
+
+// invalid UTF8
+assert_checkequal(length(ascii([190 169])), 2);
+assert_checkequal(length(ascii([223 130 172])), 3);