new file mode 100644 index 0000000..fffffff --- /dev/null +++ SkLoadICU.cpp @@ -0,0 +1,121 @@ +// Copyright 2019 Google LLC +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +#include "SkLoadICU.h" + +#if defined(_WIN32) && defined(SK_USING_THIRD_PARTY_ICU) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include + +#include +#include +#include +#include + +#include "unicode/udata.h" + +static void* win_mmap(const wchar_t* dataFile) { + if (!dataFile) { + return nullptr; + } + struct FCloseWrapper { void operator()(FILE* f) { fclose(f); } }; + std::unique_ptr stream(_wfopen(dataFile, L"rb")); + if (!stream) { + fprintf(stderr, "SkIcuLoader: datafile missing: %ls.\n", dataFile); + return nullptr; + } + int fileno = _fileno(stream.get()); + if (fileno < 0) { + fprintf(stderr, "SkIcuLoader: datafile fileno error.\n"); + return nullptr; + } + HANDLE file = (HANDLE)_get_osfhandle(fileno); + if ((HANDLE)INVALID_HANDLE_VALUE == file) { + fprintf(stderr, "SkIcuLoader: datafile handle error.\n"); + return nullptr; + } + struct CloseHandleWrapper { void operator()(HANDLE h) { CloseHandle(h); } }; + std::unique_ptr mmapHandle( + CreateFileMapping(file, nullptr, PAGE_READONLY, 0, 0, nullptr)); + if (!mmapHandle) { + fprintf(stderr, "SkIcuLoader: datafile mmap error.\n"); + return nullptr; + } + void* addr = MapViewOfFile(mmapHandle.get(), FILE_MAP_READ, 0, 0, 0); + if (nullptr == addr) { + fprintf(stderr, "SkIcuLoader: datafile view error.\n"); + return nullptr; + } + return addr; +} + +static bool init_icu(void* addr) { + UErrorCode err = U_ZERO_ERROR; + udata_setCommonData(addr, &err); + if (err != U_ZERO_ERROR) { + fprintf(stderr, "udata_setCommonData() returned %d.\n", (int)err); + return false; + } + udata_setFileAccess(UDATA_ONLY_PACKAGES, &err); + if (err != U_ZERO_ERROR) { + fprintf(stderr, "udata_setFileAccess() returned %d.\n", (int)err); + return false; + } + return true; +} + +static std::wstring get_module_path(HMODULE module) { + DWORD len; + std::wstring path; + path.resize(MAX_PATH); + + len = GetModuleFileNameW(module, (LPWSTR)path.data(), (DWORD)path.size()); + if (len > path.size()) { + path.resize(len); + len = GetModuleFileNameW(module, (LPWSTR)path.data(), (DWORD)path.size()); + } + path.resize(len); + std::size_t end = path.rfind('\\'); + if (end == std::wstring::npos) { + return std::wstring(); + } + path.resize(end); + return path; +} + +static std::wstring library_directory() { + HMODULE hModule = NULL; + GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + reinterpret_cast(&library_directory), &hModule); + return get_module_path(hModule); +} + +static std::wstring executable_directory() { + HMODULE hModule = GetModuleHandleA(NULL); + return get_module_path(hModule); +} + +static bool load_from(const std::wstring& dir) { + auto sPath = dir + L"\\icudtl.dat"; + if (void* addr = win_mmap(sPath.c_str())) { + if (init_icu(addr)) { + return true; + } + } + return false; +} + +bool SkLoadICU() { + static bool good = false; + static std::once_flag flag; + std::call_once(flag, []() { + good = load_from(executable_directory()) || load_from(library_directory()); + }); + return good; +} + +#endif // defined(_WIN32) && defined(SK_USING_THIRD_PARTY_ICU) new file mode 100644 index 0000000..fffffff --- /dev/null +++ SkLoadICU.h @@ -0,0 +1,16 @@ +/* + * Copyright 2018 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef load_icu_DEFINED +#define load_icu_DEFINED + +#if defined(_WIN32) && defined(SK_USING_THIRD_PARTY_ICU) +bool SkLoadICU(); +#else +static inline bool SkLoadICU() { return true; } +#endif // defined(_WIN32) && defined(SK_USING_THIRD_PARTY_ICU) + +#endif // load_icu_DEFINED new file mode 100644 index 0000000..fffffff --- /dev/null +++ make_data_cpp.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +# Copyright 2019 Google LLC +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +''' +Generate a source file containing the given binary data. + +Output type is C++. +''' + +from __future__ import print_function + +import os +import struct +import sys +import mmap + +def iterate_as_uint32(path): + with open(path, 'rb') as f: + s = struct.Struct('@I') + assert s.size == 4 + mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) + assert (len(mm) % s.size) == 0 + for offset in range(0, len(mm), s.size): + yield s.unpack_from(mm, offset)[0] + mm.close() + + +def convert(fmt, name, src_path, dst_path): + header, line_begin, line_end, footer = fmt + assert os.path.exists(src_path) + src = iterate_as_uint32(src_path) + with open(dst_path, 'w') as o: + o.write(header.format(name)) + while True: + line = ','.join('%d' % v for _, v in zip(range(8), src)) + if not line: + break + o.write('%s%s%s\n' % (line_begin, line, line_end)) + o.write(footer.format(name)) + + +cpp = ('#include \nextern "C" uint32_t {0}[] __attribute__((aligned(16))) = {{\n', + '', ',', '}};\n') + +if __name__ == '__main__': + print('\n'.join('>>> %r' % x for x in sys.argv)) + convert(cpp, sys.argv[1], sys.argv[2], sys.argv[3])