LCOV - code coverage report
Current view: top level - core/core/platform - SPCore-linux.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 104 241 43.2 %
Date: 2024-05-12 00:16:13 Functions: 31 56 55.4 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       3             : 
       4             :  Permission is hereby granted, free of charge, to any person obtaining a copy
       5             :  of this software and associated documentation files (the "Software"), to deal
       6             :  in the Software without restriction, including without limitation the rights
       7             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       8             :  copies of the Software, and to permit persons to whom the Software is
       9             :  furnished to do so, subject to the following conditions:
      10             : 
      11             :  The above copyright notice and this permission notice shall be included in
      12             :  all copies or substantial portions of the Software.
      13             : 
      14             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      17             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      18             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      19             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      20             :  THE SOFTWARE.
      21             :  **/
      22             : 
      23             : #include "SPString.h"
      24             : #include "SPDso.h"
      25             : 
      26             : #if LINUX
      27             : 
      28             : #include <sys/random.h>
      29             : 
      30             : namespace STAPPLER_VERSIONIZED stappler::platform {
      31             : 
      32             : constexpr uint32_t U_COMPARE_CODE_POINT_ORDER = 0x8000;
      33             : 
      34             : struct unistring_iface {
      35             :         using u8_case_fn = uint8_t * (*) (const uint8_t *s, size_t n, const char *iso639_language, void *nf, uint8_t *resultbuf, size_t *lengthp);
      36             :         using u16_case_fn = uint16_t* (*) (const uint16_t *s, size_t n, const char *iso639_language, void *nf, uint16_t *resultbuf, size_t *lengthp);
      37             : 
      38             :         int32_t (*tolower_fn) (int32_t) = nullptr;
      39             :         int32_t (*toupper_fn) (int32_t) = nullptr;
      40             :         int32_t (*totitle_fn) (int32_t) = nullptr;
      41             : 
      42             :         const char * (* uc_locale_language) () = nullptr;
      43             : 
      44             :         u8_case_fn u8_toupper = nullptr;
      45             :         u8_case_fn u8_tolower = nullptr;
      46             :         u8_case_fn u8_totitle = nullptr;
      47             : 
      48             :         int (*u8_cmp2) (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2) = nullptr;
      49             :         int (* u8_casecoll) (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2, const char *iso639_language, void *nf, int *resultp) = nullptr;
      50             : 
      51             : 
      52             :         u16_case_fn u16_toupper = nullptr;
      53             :         u16_case_fn u16_tolower = nullptr;
      54             :         u16_case_fn u16_totitle = nullptr;
      55             : 
      56             :         int (*u16_cmp2) (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2) = nullptr;
      57             :         int (* u16_casecoll) (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2, const char *iso639_language, void *nf, int *resultp) = nullptr;
      58             : 
      59          25 :         void load(Dso &handle) {
      60          25 :                 tolower_fn = handle.sym<decltype(tolower_fn)>("uc_tolower");
      61          25 :                 toupper_fn = handle.sym<decltype(toupper_fn)>("uc_toupper");
      62          25 :                 totitle_fn = handle.sym<decltype(totitle_fn)>("uc_totitle");
      63             : 
      64          25 :                 uc_locale_language = handle.sym<decltype(uc_locale_language)>("uc_locale_language");
      65             : 
      66          25 :                 u8_toupper = handle.sym<decltype(u8_toupper)>("u8_toupper");
      67          25 :                 u8_tolower = handle.sym<decltype(u8_tolower)>("u8_tolower");
      68          25 :                 u8_totitle = handle.sym<decltype(u8_totitle)>("u8_totitle");
      69             : 
      70          25 :                 u8_cmp2 = handle.sym<decltype(u8_cmp2)>("u8_cmp2");
      71          25 :                 u8_casecoll = handle.sym<decltype(u8_casecoll)>("u8_casecoll");
      72             : 
      73          25 :                 u16_toupper = handle.sym<decltype(u16_toupper)>("u16_toupper");
      74          25 :                 u16_tolower = handle.sym<decltype(u16_tolower)>("u16_tolower");
      75          25 :                 u16_totitle = handle.sym<decltype(u16_totitle)>("u16_totitle");
      76             : 
      77          25 :                 u16_cmp2 = handle.sym<decltype(u16_cmp2)>("u16_cmp2");
      78          25 :                 u16_casecoll = handle.sym<decltype(u16_casecoll)>("u16_casecoll");
      79          25 :         }
      80             : 
      81          25 :         explicit operator bool() const {
      82          25 :                 return uc_locale_language
      83          25 :                                 && tolower_fn && toupper_fn && totitle_fn
      84          25 :                                 && u8_toupper && u8_tolower && u8_totitle && u8_cmp2 && u8_casecoll
      85          50 :                                 && u16_toupper && u16_tolower && u16_totitle && u16_cmp2 && u16_casecoll;
      86             :         }
      87             : 
      88           0 :         void clear() {
      89           0 :                 tolower_fn = nullptr;
      90           0 :                 toupper_fn = nullptr;
      91           0 :                 totitle_fn = nullptr;
      92             : 
      93           0 :                 uc_locale_language = nullptr;
      94             : 
      95           0 :                 u8_toupper = nullptr;
      96           0 :                 u8_tolower = nullptr;
      97           0 :                 u8_totitle = nullptr;
      98             : 
      99           0 :                 u8_cmp2 = nullptr;
     100           0 :                 u8_casecoll = nullptr;
     101             : 
     102           0 :                 u16_toupper = nullptr;
     103           0 :                 u16_tolower = nullptr;
     104           0 :                 u16_totitle = nullptr;
     105             : 
     106           0 :                 u16_cmp2 = nullptr;
     107           0 :                 u16_casecoll = nullptr;
     108           0 :         }
     109             : };
     110             : 
     111             : struct icu_iface {
     112             :         using case_fn = int32_t (*) (char16_t *dest, int32_t destCapacity, const char16_t *src, int32_t srcLength,
     113             :                         const char *locale, int *pErrorCode);
     114             :         using case_iter_fn = int32_t (*) (char16_t *dest, int32_t destCapacity, const char16_t *src, int32_t srcLength,
     115             :                         void *iter, const char *locale, int *pErrorCode);
     116             : 
     117             :         using cmp_fn = int32_t (*) (const char16_t *s1, int32_t length1, const char16_t *s2, int32_t length2, int8_t codePointOrder);
     118             :         using case_cmp_fn =  int32_t (*) ( const char16_t *s1, int32_t length1, const char16_t *s2, int32_t length2,
     119             :                         uint32_t options, int *pErrorCode);
     120             : 
     121             :         int32_t (*tolower_fn) (int32_t) = nullptr;
     122             :         int32_t (*toupper_fn) (int32_t) = nullptr;
     123             :         int32_t (*totitle_fn) (int32_t) = nullptr;
     124             : 
     125             :         case_fn u_strToLower = nullptr;
     126             :         case_fn u_strToUpper = nullptr;
     127             :         case_iter_fn u_strToTitle = nullptr;
     128             : 
     129             :         cmp_fn u_strCompare = nullptr;
     130             :         case_cmp_fn u_strCaseCompare = nullptr;
     131             : 
     132             :         static void *loadIcu(Dso &h, const char *name, StringView ver) {
     133             :                 char buf[256] = { 0 };
     134             :                 auto ret = h.sym<void *>(name);
     135             :                 if (!ret && !ver.empty()) {
     136             :                         strcpy(buf, name);
     137             :                         strcat(buf, "_");
     138             :                         strncat(buf, ver.data(), ver.size());
     139             : 
     140             :                         ret = h.sym<void *>(buf);
     141             :                 }
     142             :                 return ret;
     143             :         }
     144             : 
     145             :         void load(Dso &handle, StringView verSuffix) {
     146             :                 tolower_fn = reinterpret_cast<decltype(tolower_fn)>(loadIcu(handle, "u_tolower", verSuffix));
     147             :                 toupper_fn = reinterpret_cast<decltype(toupper_fn)>(loadIcu(handle, "u_toupper", verSuffix));
     148             :                 totitle_fn = reinterpret_cast<decltype(totitle_fn)>(loadIcu(handle, "u_totitle", verSuffix));
     149             :                 u_strToLower = reinterpret_cast<decltype(u_strToLower)>(loadIcu(handle, "u_strToLower", verSuffix));
     150             :                 u_strToUpper = reinterpret_cast<decltype(u_strToUpper)>(loadIcu(handle, "u_strToUpper", verSuffix));
     151             :                 u_strToTitle = reinterpret_cast<decltype(u_strToTitle)>(loadIcu(handle, "u_strToTitle", verSuffix));
     152             :                 u_strCompare = reinterpret_cast<decltype(u_strCompare)>(loadIcu(handle, "u_strCompare", verSuffix));
     153             :                 u_strCaseCompare = reinterpret_cast<decltype(u_strCaseCompare)>(loadIcu(handle, "u_strCaseCompare", verSuffix));
     154             :         }
     155             : 
     156       28530 :         explicit operator bool() const {
     157           0 :                 return tolower_fn && toupper_fn && totitle_fn
     158       28530 :                                 && u_strToLower && u_strToUpper && u_strToTitle && u_strCompare && u_strCaseCompare;
     159             :         }
     160             : 
     161             :         void clear() {
     162             :                 tolower_fn = nullptr;
     163             :                 toupper_fn = nullptr;
     164             :                 totitle_fn = nullptr;
     165             :                 u_strToLower = nullptr;
     166             :                 u_strToUpper = nullptr;
     167             :                 u_strToTitle = nullptr;
     168             :                 u_strCompare = nullptr;
     169             :                 u_strCaseCompare = nullptr;
     170             :         }
     171             : };
     172             : 
     173             : struct i18n {
     174          25 :         static i18n *getInstance() {
     175          25 :                 static i18n s_instance;
     176          25 :                 return &s_instance;
     177             :         }
     178             : 
     179          25 :         i18n() {
     180             :                 // try unistring
     181             :                 // try version 0 or 1 if no general symlink
     182          25 :                 _handle = Dso("libunistring.so");
     183          25 :                 if (!_handle) {
     184           0 :                         _handle = Dso("libunistring.so.1");
     185             :                 }
     186          25 :                 if (!_handle) {
     187           0 :                         _handle = Dso("libunistring.so.0");
     188             :                 }
     189          25 :                 if (_handle) {
     190          25 :                         unistring.load(_handle);
     191          25 :                         if (unistring) {
     192          25 :                                 return;
     193             :                         } else {
     194           0 :                                 unistring.clear();
     195           0 :                                 _handle.close();
     196             :                         }
     197             :                 }
     198             : 
     199             :                 // try ICU
     200           0 :                 char buf[256] = { 0 };
     201           0 :                 const char *paramName = nullptr;
     202           0 :                 StringView verSuffix;
     203             : 
     204           0 :                 auto dbg = Dso("libicutu.so");
     205           0 :                 if (dbg) {
     206           0 :                         auto getSystemParameterNameByIndex = dbg.sym<const char *(*)(int32_t)>("udbg_getSystemParameterNameByIndex");
     207           0 :                         auto getSystemParameterValueByIndex = dbg.sym<int32_t (*) (int32_t i, char *, int32_t, int *)>("udbg_getSystemParameterValueByIndex");
     208             : 
     209           0 :                         if (getSystemParameterNameByIndex && getSystemParameterValueByIndex) {
     210             :                                 int status;
     211           0 :                                 for (int32_t i = 0; (paramName = getSystemParameterNameByIndex(i)) != nullptr; ++i) {
     212           0 :                                         getSystemParameterValueByIndex(i, buf, 256, &status);
     213           0 :                                         if (StringView(paramName) == "version") {
     214           0 :                                                 break;
     215             :                                         }
     216             :                                 }
     217             :                         }
     218             :                 }
     219             : 
     220           0 :                 if (StringView(paramName) == "version") {
     221           0 :                         verSuffix = StringView(buf).readUntil<StringView::Chars<'.'>>();
     222             :                 }
     223             : 
     224           0 :                 _handle = Dso("libicuuc.so");
     225           0 :                 if (_handle) {
     226             : 
     227             :                 }
     228           0 :                 _handle.close();
     229           0 :         }
     230             : 
     231          25 :         ~i18n() { }
     232             : 
     233       22050 :         char32_t tolower(char32_t c) {
     234       22050 :                 return _handle ? char32_t(icu ? icu.tolower_fn(int32_t(c)) : unistring.tolower_fn(int32_t(c))) : 0;
     235             :         }
     236             : 
     237        6480 :         char32_t toupper(char32_t c) {
     238        6480 :                 return _handle ? char32_t(icu ? icu.toupper_fn(int32_t(c)) : unistring.toupper_fn(int32_t(c))) : 0;
     239             :         }
     240             : 
     241           0 :         char32_t totitle(char32_t c) {
     242           0 :                 return _handle ? char32_t(icu ? icu.totitle_fn(int32_t(c)) : unistring.totitle_fn(int32_t(c))) : 0;
     243             :         }
     244             : 
     245             :         template <typename Interface>
     246           0 :         auto applyIcoFunction(WideStringView data, icu_iface::case_fn icuFn) {
     247           0 :                 typename Interface::WideStringType ret;
     248           0 :                 ret.resize(data.size());
     249             : 
     250           0 :                 int status = 0;
     251           0 :                 auto len = icuFn(ret.data(), ret.size(), data.data(), data.size(), NULL, &status);
     252           0 :                 if (len <= int32_t(ret.size())) {
     253           0 :                         ret.resize(len);
     254             :                 } else {
     255           0 :                         ret.resize(len);
     256           0 :                         icuFn(ret.data(), ret.size(), data.data(), data.size(), NULL, &status);
     257             :                 }
     258           0 :                 return ret;
     259           0 :         }
     260             : 
     261             :         template <typename Interface>
     262       19889 :         auto applyUnistringFunction(StringView data, unistring_iface::u8_case_fn ustrFn) {
     263       19889 :                 typename Interface::StringType ret;
     264       19889 :                 ret.resize(data.size());
     265             : 
     266       19889 :                 size_t targetSize = ret.size();
     267       19889 :                 auto buf = ustrFn((const uint8_t *)data.data(), data.size(), unistring.uc_locale_language(), NULL,
     268       19889 :                                 (uint8_t *)ret.data(), &targetSize);
     269       19889 :                 if (targetSize > ret.size()) {
     270           0 :                         ret = typename Interface::StringType((char *)buf);
     271           0 :                         ::free(buf);
     272             :                 } else {
     273       19889 :                         ret.resize(targetSize);
     274             :                 }
     275       39778 :                 return ret;
     276           0 :         }
     277             : 
     278             :         template <typename Interface>
     279      111550 :         auto applyUnistringFunction(WideStringView data, unistring_iface::u16_case_fn ustrFn) {
     280      111550 :                 typename Interface::WideStringType ret;
     281      111550 :                 ret.resize(data.size());
     282             : 
     283      111550 :                 size_t targetSize = ret.size();
     284      111550 :                 auto buf = ustrFn((const uint16_t *)data.data(), data.size(), unistring.uc_locale_language(), NULL,
     285      111550 :                                 (uint16_t *)ret.data(), &targetSize);
     286      111550 :                 if (targetSize > ret.size()) {
     287           0 :                         ret = typename Interface::WideStringType((char16_t *)buf);
     288           0 :                         ::free(buf);
     289             :                 } else {
     290      111550 :                         ret.resize(targetSize);
     291             :                 }
     292      223100 :                 return ret;
     293           0 :         }
     294             : 
     295             :         template <typename Interface>
     296       19839 :         auto applyFunction(StringView data, icu_iface::case_fn icuFn, unistring_iface::u8_case_fn ustrFn) {
     297       19839 :                 if (!_handle) {
     298           0 :                         return data.str<Interface>();
     299             :                 }
     300             : 
     301       19839 :                 if (icuFn) {
     302             :                         return string::toUtf8<Interface>(
     303             :                                 applyIcoFunction<Interface>(
     304             :                                         string::toUtf16<Interface>(data),
     305           0 :                                         icuFn));
     306             :                 } else {
     307       19839 :                         return applyUnistringFunction<Interface>(data, ustrFn);
     308             :                 }
     309             :         }
     310             : 
     311             :         template <typename Interface>
     312      111550 :         auto applyFunction(WideStringView data, icu_iface::case_fn icuFn, unistring_iface::u16_case_fn ustrFn) {
     313      111550 :                 if (!_handle) {
     314           0 :                         return data.str<Interface>();
     315             :                 }
     316             : 
     317      111550 :                 if (icuFn) {
     318           0 :                         return applyIcoFunction<Interface>(data, icuFn);
     319             :                 } else {
     320      111550 :                         return applyUnistringFunction<Interface>(data, ustrFn);
     321             :                 }
     322             :         }
     323             : 
     324             :         template <typename Interface>
     325       19506 :         auto tolower(StringView data) {
     326       19506 :                 return applyFunction<Interface>(data, icu.u_strToLower, unistring.u8_tolower);
     327             :         }
     328             : 
     329             :         template <typename Interface>
     330      111550 :         auto tolower(WideStringView data) {
     331      111550 :                 return applyFunction<Interface>(data, icu.u_strToLower, unistring.u16_tolower);
     332             :         }
     333             : 
     334             :         template <typename Interface>
     335         333 :         auto toupper(StringView data) {
     336         333 :                 return applyFunction<Interface>(data, icu.u_strToUpper, unistring.u8_toupper);
     337             :         }
     338             : 
     339             :         template <typename Interface>
     340           0 :         auto toupper(WideStringView data) {
     341           0 :                 return applyFunction<Interface>(data, icu.u_strToUpper, unistring.u16_toupper);
     342             :         }
     343             : 
     344             :         template <typename Interface>
     345          50 :         auto totitle(StringView data) {
     346          50 :                 if (!_handle) {
     347           0 :                         return data.str<Interface>();
     348             :                 }
     349             : 
     350          50 :                 if (icu.u_strToTitle) {
     351           0 :                         return string::toUtf8<Interface>(totitle<Interface>(string::toUtf16<Interface>(data)));
     352             :                 } else {
     353          50 :                         return applyUnistringFunction<Interface>(data, unistring.u8_totitle);
     354             :                 }
     355             :         }
     356             : 
     357             :         template <typename Interface>
     358           0 :         auto totitle(WideStringView data) {
     359           0 :                 if (!_handle) {
     360           0 :                         return data.str<Interface>();
     361             :                 }
     362             : 
     363           0 :                 typename Interface::WideStringType ret;
     364           0 :                 ret.resize(data.size());
     365             : 
     366           0 :                 if (icu.u_strToTitle) {
     367           0 :                         int status = 0;
     368           0 :                         auto len = icu.u_strToTitle(ret.data(), ret.size(), data.data(), data.size(), NULL, NULL, &status);
     369           0 :                         if (len <= int32_t(ret.size())) {
     370           0 :                                 ret.resize(len);
     371             :                         } else {
     372           0 :                                 ret.resize(len);
     373           0 :                                 icu.u_strToTitle(ret.data(), ret.size(), data.data(), data.size(), NULL, NULL, &status);
     374             :                         }
     375             :                 } else {
     376           0 :                         return applyUnistringFunction<Interface>(data, unistring.u16_totitle);
     377             :                 }
     378             : 
     379           0 :                 return ret;
     380           0 :         }
     381             : 
     382           0 :         int compare(StringView l, StringView r) {
     383           0 :                 if (unistring.u8_cmp2) {
     384           0 :                         return unistring.u8_cmp2((const uint8_t *)l.data(), l.size(), (const uint8_t *)r.data(), r.size());
     385           0 :                 } else if (icu.u_strCompare) {
     386           0 :                         auto lStr = string::toUtf16<memory::StandartInterface>(l);
     387           0 :                         auto rStr = string::toUtf16<memory::StandartInterface>(r);
     388           0 :                         return icu.u_strCompare(lStr.data(), lStr.size(), rStr.data(), rStr.size(), 1);
     389           0 :                 }
     390           0 :                 return string::compare_c(l, r);
     391             :         }
     392             : 
     393           0 :         int compare(WideStringView l, WideStringView r) {
     394           0 :                 if (unistring.u16_cmp2) {
     395           0 :                         return unistring.u16_cmp2((const uint16_t *)l.data(), l.size(), (const uint16_t *)r.data(), r.size());
     396           0 :                 } else if (icu.u_strCompare) {
     397           0 :                         return icu.u_strCompare(l.data(), l.size(), r.data(), r.size(), 1);
     398             :                 }
     399           0 :                 return string::compare_c(l, r);
     400             :         }
     401       15925 :         int caseCompare(StringView l, StringView r) {
     402       15925 :                 if (unistring.u8_casecoll) {
     403       15925 :                         int32_t ret = 0;
     404       15925 :                         if (unistring.u8_casecoll((const uint8_t *)l.data(), l.size(), (const uint8_t *)r.data(), r.size(), unistring.uc_locale_language(), nullptr, &ret) == 0) {
     405         250 :                                 return ret;
     406             :                         }
     407           0 :                 } else if (icu.u_strCaseCompare) {
     408           0 :                         int status = 0;
     409           0 :                         auto lStr = string::toUtf16<memory::StandartInterface>(l);
     410           0 :                         auto rStr = string::toUtf16<memory::StandartInterface>(r);
     411           0 :                         return icu.u_strCaseCompare(lStr.data(), lStr.size(), rStr.data(), rStr.size(), U_COMPARE_CODE_POINT_ORDER, &status);
     412           0 :                 }
     413       15675 :                 return string::caseCompare_c(l, r);
     414             :         }
     415             : 
     416           0 :         int caseCompare(WideStringView l, WideStringView r) {
     417           0 :                 if (unistring.u16_casecoll) {
     418           0 :                         int32_t ret = 0;
     419           0 :                         if (unistring.u16_casecoll((const uint16_t *)l.data(), l.size(), (const uint16_t *)r.data(), r.size(), unistring.uc_locale_language(), nullptr, &ret) == 0) {
     420           0 :                                 return ret;
     421             :                         }
     422           0 :                 } else if (icu.u_strCaseCompare) {
     423           0 :                         int status = 0;
     424           0 :                         return icu.u_strCaseCompare(l.data(), l.size(), r.data(), r.size(), U_COMPARE_CODE_POINT_ORDER, &status);
     425             :                 }
     426           0 :                 return string::caseCompare_c(l, r);
     427             :         }
     428             : 
     429             :         icu_iface icu;
     430             :         unistring_iface unistring;
     431             : 
     432             :         Dso _handle;
     433             : };
     434             : 
     435             : static i18n *s_instance = i18n::getInstance();
     436             : 
     437       22050 : char32_t tolower(char32_t c) {
     438       22050 :         return s_instance->tolower(c);
     439             : }
     440             : 
     441        6480 : char32_t toupper(char32_t c) {
     442        6480 :         return s_instance->toupper(c);
     443             : }
     444             : 
     445           0 : char32_t totitle(char32_t c) {
     446           0 :         return s_instance->totitle(c);
     447             : }
     448             : 
     449             : template <>
     450         750 : auto tolower<memory::PoolInterface>(StringView data) -> memory::PoolInterface::StringType {
     451         750 :         return s_instance->tolower<memory::PoolInterface>(data);
     452             : }
     453             : 
     454             : template <>
     455       18756 : auto tolower<memory::StandartInterface>(StringView data) -> memory::StandartInterface::StringType {
     456       18756 :         return s_instance->tolower<memory::StandartInterface>(data);
     457             : }
     458             : 
     459             : template <>
     460         183 : auto toupper<memory::PoolInterface>(StringView data) -> memory::PoolInterface::StringType {
     461         183 :         return s_instance->toupper<memory::PoolInterface>(data);
     462             : }
     463             : 
     464             : template <>
     465         150 : auto toupper<memory::StandartInterface>(StringView data) -> memory::StandartInterface::StringType {
     466         150 :         return s_instance->toupper<memory::StandartInterface>(data);
     467             : }
     468             : 
     469             : template <>
     470           0 : auto totitle<memory::PoolInterface>(StringView data) -> memory::PoolInterface::StringType {
     471           0 :         return s_instance->totitle<memory::PoolInterface>(data);
     472             : }
     473             : 
     474             : template <>
     475          50 : auto totitle<memory::StandartInterface>(StringView data) -> memory::StandartInterface::StringType {
     476          50 :         return s_instance->totitle<memory::StandartInterface>(data);
     477             : }
     478             : 
     479             : template <>
     480      111550 : auto tolower<memory::PoolInterface>(WideStringView data) -> memory::PoolInterface::WideStringType {
     481      111550 :         return s_instance->tolower<memory::PoolInterface>(data);
     482             : }
     483             : 
     484             : template <>
     485           0 : auto tolower<memory::StandartInterface>(WideStringView data) -> memory::StandartInterface::WideStringType {
     486           0 :         return s_instance->tolower<memory::StandartInterface>(data);
     487             : }
     488             : 
     489             : template <>
     490           0 : auto toupper<memory::PoolInterface>(WideStringView data) -> memory::PoolInterface::WideStringType {
     491           0 :         return s_instance->toupper<memory::PoolInterface>(data);
     492             : }
     493             : 
     494             : template <>
     495           0 : auto toupper<memory::StandartInterface>(WideStringView data) -> memory::StandartInterface::WideStringType {
     496           0 :         return s_instance->toupper<memory::StandartInterface>(data);
     497             : }
     498             : 
     499             : template <>
     500           0 : auto totitle<memory::PoolInterface>(WideStringView data) -> memory::PoolInterface::WideStringType {
     501           0 :         return s_instance->totitle<memory::PoolInterface>(data);
     502             : }
     503             : 
     504             : template <>
     505           0 : auto totitle<memory::StandartInterface>(WideStringView data) -> memory::StandartInterface::WideStringType {
     506           0 :         return s_instance->totitle<memory::StandartInterface>(data);
     507             : }
     508             : 
     509           0 : int compare_u(StringView l, StringView r) {
     510           0 :         return s_instance->compare(l, r);
     511             : }
     512             : 
     513           0 : int compare_u(WideStringView l, WideStringView r) {
     514           0 :         return s_instance->compare(l, r);
     515             : }
     516             : 
     517       15925 : int caseCompare_u(StringView l, StringView r) {
     518       15925 :         return s_instance->caseCompare(l, r);
     519             : }
     520             : 
     521           0 : int caseCompare_u(WideStringView l, WideStringView r) {
     522           0 :         return s_instance->caseCompare(l, r);
     523             : }
     524             : 
     525        2957 : size_t makeRandomBytes(uint8_t * buf, size_t count) {
     526        2957 :         size_t generated = 0;
     527        2957 :         auto ret = ::getrandom(buf, count, GRND_RANDOM | GRND_NONBLOCK);
     528        2957 :         if (ret < ssize_t(count)) {
     529           0 :                 buf += ret;
     530           0 :                 count -= ret;
     531           0 :                 generated += ret;
     532             : 
     533           0 :                 ret = ::getrandom(buf, count, GRND_NONBLOCK);
     534           0 :                 if (ret >= 0) {
     535           0 :                         generated += ret;
     536             :                 }
     537             :         }
     538        2957 :         return generated;
     539             : }
     540             : 
     541             : }
     542             : 
     543             : #endif

Generated by: LCOV version 1.14