aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports/SkOSFile_stdio.cpp
diff options
context:
space:
mode:
authorGravatar Hal Canary <halcanary@google.com>2018-03-01 12:32:18 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-01 19:03:19 +0000
commit2d0e1248d6eef36ecc510785e9bf8a28530c56fe (patch)
treeae146e3478a79c02508a466a6a77e8d03440d943 /src/ports/SkOSFile_stdio.cpp
parent44b61204d9f5681b9474db017577d56f42a32d66 (diff)
SkString: fix ::setUTF16
Change-Id: I7ab4af9ae55a43cc05f81b0c236f29a64beac982 Reviewed-on: https://skia-review.googlesource.com/111223 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Hal Canary <halcanary@google.com>
Diffstat (limited to 'src/ports/SkOSFile_stdio.cpp')
-rw-r--r--src/ports/SkOSFile_stdio.cpp50
1 files changed, 45 insertions, 5 deletions
diff --git a/src/ports/SkOSFile_stdio.cpp b/src/ports/SkOSFile_stdio.cpp
index 7cdc549df6..d8541c21c0 100644
--- a/src/ports/SkOSFile_stdio.cpp
+++ b/src/ports/SkOSFile_stdio.cpp
@@ -19,14 +19,53 @@
#ifdef _WIN32
#include <direct.h>
#include <io.h>
+#include <vector>
+#include "SkUtils.h"
#endif
#ifdef SK_BUILD_FOR_IOS
#include "SkOSFile_ios.h"
#endif
+#ifdef _WIN32
+static bool is_ascii(const char* s) {
+ while (char v = *s++) {
+ if ((v & 0x80) != 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static FILE* fopen_win(const char* utf8path, const char* perm) {
+ if (is_ascii(utf8path)) {
+ return fopen(utf8path, perm);
+ }
+
+ const char* ptr = utf8path;
+ const char* end = utf8path + strlen(utf8path);
+ size_t n = 0;
+ while (ptr < end) {
+ SkUnichar u = SkUTF8_NextUnicharWithError(&ptr, end);
+ if (u < 0) {
+ return nullptr; // malformed UTF-8
+ }
+ n += SkUTF16_FromUnichar(u);
+ }
+ std::vector<uint16_t> wchars(n + 1);
+ uint16_t* out = wchars.data();
+ for (const char* ptr = utf8path; ptr < end;) {
+ out += SkUTF16_FromUnichar(SkUTF8_NextUnicharWithError(&ptr, end), out);
+ }
+ SkASSERT(out == &wchars[n]);
+ *out = 0; // final null
+ wchar_t wperms[4] = {(wchar_t)perm[0], (wchar_t)perm[1], (wchar_t)perm[2], (wchar_t)perm[3]};
+ return _wfopen((wchar_t*)wchars.data(), wperms);
+}
+#endif
+
FILE* sk_fopen(const char path[], SkFILE_Flags flags) {
- char perm[4];
+ char perm[4] = {0, 0, 0, 0};
char* p = perm;
if (flags & kRead_SkFILE_Flag) {
@@ -35,13 +74,14 @@ FILE* sk_fopen(const char path[], SkFILE_Flags flags) {
if (flags & kWrite_SkFILE_Flag) {
*p++ = 'w';
}
- *p++ = 'b';
- *p = 0;
+ *p = 'b';
- //TODO: on Windows fopen is just ASCII or the current code page,
- //convert to utf16 and use _wfopen
FILE* file = nullptr;
+#ifdef _WIN32
+ file = fopen_win(path, perm);
+#else
file = fopen(path, perm);
+#endif
#ifdef SK_BUILD_FOR_IOS
// if not found in default path and read-only, try to open from bundle
if (!file && kRead_SkFILE_Flag == flags) {