/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ // Needed when #include below includes Boost 1.65.1 // workdir/UnpackedTarball/boost/boost/locale/format.hpp using "std::auto_ptr d;", but must // come very early here in case is already (indirectly) included earlier: #include #if HAVE_LIBCXX && __cplusplus >= 201703L #define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR #elif defined _MSC_VER && __cplusplus >= 201703L #define _HAS_AUTO_PTR_ETC 1 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { OUString createFromUtf8(const char* data, size_t size) { OUString aTarget; bool bSuccess = rtl_convertStringToUString(&aTarget.pData, data, size, RTL_TEXTENCODING_UTF8, RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR); (void) bSuccess; assert(bSuccess); return aTarget; } OString genKeyId(const OString& rGenerator) { sal_uInt32 nCRC = rtl_crc32(0, rGenerator.getStr(), rGenerator.getLength()); // Use simple ASCII characters, exclude I, l, 1 and O, 0 to avoid confusing IDs static const char sSymbols[] = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789"; char sKeyId[6]; for (short nKeyInd = 0; nKeyInd < 5; ++nKeyInd) { sKeyId[nKeyInd] = sSymbols[(nCRC & 63) % strlen(sSymbols)]; nCRC >>= 6; } sKeyId[5] = '\0'; return OString(sKeyId); } } namespace Translate { std::locale Create(const sal_Char* pPrefixName, const LanguageTag& rLocale) { static std::unordered_map aCache; OString sIdentifier = rLocale.getGlibcLocaleString(".UTF-8").toUtf8(); OString sUnique = sIdentifier + OString(pPrefixName); auto aFind = aCache.find(sUnique); if (aFind != aCache.end()) return aFind->second; boost::locale::generator gen; gen.characters(boost::locale::char_facet); gen.categories(boost::locale::message_facet | boost::locale::information_facet); OUString uri("$BRAND_BASE_DIR/$BRAND_SHARE_RESOURCE_SUBDIR/"); rtl::Bootstrap::expandMacros(uri); OUString path; osl::File::getSystemPathFromFileURL(uri, path); gen.add_messages_path(OUStringToOString(path, osl_getThreadTextEncoding()).getStr()); gen.add_messages_domain(pPrefixName); std::locale aRet(gen(sIdentifier.getStr())); aCache[sUnique] = aRet; return aRet; } OUString get(const char* pContextAndId, const std::locale &loc) { OString sContext; const char *pId = strchr(pContextAndId, '\004'); if (!pId) pId = pContextAndId; else { sContext = OString(pContextAndId, pId - pContextAndId); ++pId; } //if its a key id locale, generate it here if (std::use_facet(loc).language() == "qtz") { OString sKeyId(genKeyId(OString(pContextAndId).replace('\004', '|'))); return OUString::fromUtf8(sKeyId) + OUStringLiteral1(0x2016) + createFromUtf8(pId, strlen(pId)); } //otherwise translate it const std::string ret = boost::locale::pgettext(sContext.getStr(), pId, loc); return ExpandVariables(createFromUtf8(ret.data(), ret.size())); } static ResHookProc pImplResHookProc = nullptr; OUString ExpandVariables(const OUString& rString) { if (pImplResHookProc) return pImplResHookProc(rString); return rString; } void SetReadStringHook( ResHookProc pProc ) { pImplResHookProc = pProc; } ResHookProc GetReadStringHook() { return pImplResHookProc; } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */