# endif
#endif
+#if U_PLATFORM_HAS_WINUWP_API != 0
+// Helper function to get the ICU Data Directory under the Windows directory location.
+static BOOL U_CALLCONV getIcuDataDirectoryUnderWindowsDirectory(char* directoryBuffer, UINT bufferLength)
+{
+#if defined(ICU_DATA_DIR_WINDOWS)
+ wchar_t windowsPath[MAX_PATH];
+ char windowsPathUtf8[MAX_PATH];
+
+ UINT length = GetSystemWindowsDirectoryW(windowsPath, UPRV_LENGTHOF(windowsPath));
+ if ((length > 0) && (length < (UPRV_LENGTHOF(windowsPath) - 1))) {
+ // Convert UTF-16 to a UTF-8 string.
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t windowsPathUtf8Len = 0;
+ u_strToUTF8(windowsPathUtf8, static_cast<int32_t>(UPRV_LENGTHOF(windowsPathUtf8)),
+ &windowsPathUtf8Len, reinterpret_cast<const UChar*>(windowsPath), -1, &status);
+
+ if (U_SUCCESS(status) && (status != U_STRING_NOT_TERMINATED_WARNING) &&
+ (windowsPathUtf8Len < (UPRV_LENGTHOF(windowsPathUtf8) - 1))) {
+ // Ensure it always has a separator, so we can append the ICU data path.
+ if (windowsPathUtf8[windowsPathUtf8Len - 1] != U_FILE_SEP_CHAR) {
+ windowsPathUtf8[windowsPathUtf8Len++] = U_FILE_SEP_CHAR;
+ windowsPathUtf8[windowsPathUtf8Len] = '\0';
+ }
+ // Check if the concatenated string will fit.
+ if ((windowsPathUtf8Len + UPRV_LENGTHOF(ICU_DATA_DIR_WINDOWS)) < bufferLength) {
+ uprv_strcpy(directoryBuffer, windowsPathUtf8);
+ uprv_strcat(directoryBuffer, ICU_DATA_DIR_WINDOWS);
+ return TRUE;
+ }
+ }
+ }
+#endif
+
+ return FALSE;
+}
+#endif
+
static void U_CALLCONV dataDirectoryInitFn() {
/* If we already have the directory, then return immediately. Will happen if user called
* u_setDataDirectory().
}
#endif
-#if defined(ICU_DATA_DIR_WINDOWS) && U_PLATFORM_HAS_WINUWP_API != 0
- // Use data from the %windir%\globalization\icu directory
- // This is only available if ICU is built as a system component
+#if U_PLATFORM_HAS_WINUWP_API != 0 && defined(ICU_DATA_DIR_WINDOWS)
char datadir_path_buffer[MAX_PATH];
- UINT length = GetWindowsDirectoryA(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer));
- if (length > 0 && length < (UPRV_LENGTHOF(datadir_path_buffer) - sizeof(ICU_DATA_DIR_WINDOWS) - 1))
- {
- if (datadir_path_buffer[length - 1] != '\\')
- {
- datadir_path_buffer[length++] = '\\';
- datadir_path_buffer[length] = '\0';
- }
-
- if ((length + 1 + sizeof(ICU_DATA_DIR_WINDOWS)) < UPRV_LENGTHOF(datadir_path_buffer))
- {
- uprv_strcat(datadir_path_buffer, ICU_DATA_DIR_WINDOWS);
- path = datadir_path_buffer;
- }
+ if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
+ path = datadir_path_buffer;
}
#endif
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
-#if U_PLATFORM_HAS_WINUWP_API == 0
- const char *dir = getenv("ICU_TIMEZONE_FILES_DIR");
-#else
- // TODO: UWP does not support alternate timezone data directories at this time
+
const char *dir = "";
+
+#if U_PLATFORM_HAS_WINUWP_API != 0
+ // The UWP version does not support the environment variable setting, but can possibly pick them up from the Windows directory.
+ char datadir_path_buffer[MAX_PATH];
+ if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
+ dir = datadir_path_buffer;
+ }
+#else
+ dir = getenv("ICU_TIMEZONE_FILES_DIR");
#endif // U_PLATFORM_HAS_WINUWP_API
+
#if defined(U_TIMEZONE_FILES_DIR)
if (dir == NULL) {
+ // Build time configuration setting.
dir = TO_STRING(U_TIMEZONE_FILES_DIR);
}
#endif
+
if (dir == NULL) {
dir = "";
}
+
setTimeZoneFilesDir(dir, status);
}
#include "uposixdefs.h"
#include "unicode/putil.h"
+#include "unicode/ustring.h"
#include "udatamem.h"
#include "umapfile.h"
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, NULL);
#else
- // First we need to go from char to UTF-16
- // u_UCharsToChars could work but it requires length.
- WCHAR utf16Path[MAX_PATH];
- int32_t i;
- for (i = 0; i < UPRV_LENGTHOF(utf16Path); i++)
- {
- utf16Path[i] = path[i];
- if (path[i] == '\0')
- {
- break;
- }
+ // Convert from UTF-8 string to UTF-16 string.
+ wchar_t utf16Path[MAX_PATH];
+ int32_t pathUtf16Len = 0;
+ u_strFromUTF8(reinterpret_cast<UChar*>(utf16Path), static_cast<int32_t>(UPRV_LENGTHOF(utf16Path)), &pathUtf16Len, path, -1, status);
+
+ if (U_FAILURE(*status)) {
+ return FALSE;
}
- if (i >= UPRV_LENGTHOF(utf16Path))
- {
- // Ran out of room, unlikely but be safe
- utf16Path[UPRV_LENGTHOF(utf16Path) - 1] = '\0';
+ if (*status == U_STRING_NOT_TERMINATED_WARNING) {
+ // Report back an error instead of a warning.
+ *status = U_BUFFER_OVERFLOW_ERROR;
+ return FALSE;
}
// TODO: Is it worth setting extended parameters to specify random access?