LCOV - code coverage report
Current view: top level - core/core/string - SPString.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 137 148 92.6 %
Date: 2024-05-12 00:16:13 Functions: 287 526 54.6 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef STAPPLER_CORE_STRING_SPSTRING_H_
      25             : #define STAPPLER_CORE_STRING_SPSTRING_H_
      26             : 
      27             : #include "SPCoreCrypto.h"
      28             : #include "SPStringStream.h"
      29             : 
      30             : namespace STAPPLER_VERSIONIZED stappler::string {
      31             : 
      32         945 : inline size_t getUtf16Length(char32_t c) { return unicode::utf16EncodeLength(c); }
      33             : size_t getUtf16Length(const StringView &str);
      34             : size_t getUtf16HtmlLength(const StringView &str);
      35             : 
      36             : inline size_t getUtf8Length(char32_t c) { return unicode::utf8EncodeLength(c); }
      37             : inline size_t getUtf8Length(char16_t c) { return unicode::utf8EncodeLength(c); }
      38             : size_t getUtf8HtmlLength(const StringView &str);
      39             : size_t getUtf8Length(const WideStringView &str);
      40             : 
      41             : char charToKoi8r(char16_t c);
      42             : 
      43             : template <typename StringType>
      44             : struct InterfaceForString;
      45             : 
      46             : template <>
      47             : struct InterfaceForString<typename memory::StandartInterface::StringType> {
      48             :         using Type = memory::StandartInterface;
      49             : };
      50             : 
      51             : template <>
      52             : struct InterfaceForString<typename memory::StandartInterface::WideStringType> {
      53             :         using Type = memory::StandartInterface;
      54             : };
      55             : 
      56             : template <>
      57             : struct InterfaceForString<typename memory::PoolInterface::StringType> {
      58             :         using Type = memory::PoolInterface;
      59             : };
      60             : 
      61             : template <>
      62             : struct InterfaceForString<typename memory::PoolInterface::WideStringType> {
      63             :         using Type = memory::PoolInterface;
      64             : };
      65             : 
      66             : 
      67             : template <>
      68             : struct InterfaceForString<const typename memory::StandartInterface::StringType> {
      69             :         using Type = memory::StandartInterface;
      70             : };
      71             : 
      72             : template <>
      73             : struct InterfaceForString<const typename memory::StandartInterface::WideStringType> {
      74             :         using Type = memory::StandartInterface;
      75             : };
      76             : 
      77             : template <>
      78             : struct InterfaceForString<const typename memory::PoolInterface::StringType> {
      79             :         using Type = memory::PoolInterface;
      80             : };
      81             : 
      82             : template <>
      83             : struct InterfaceForString<const typename memory::PoolInterface::WideStringType> {
      84             :         using Type = memory::PoolInterface;
      85             : };
      86             : 
      87             : bool isValidUtf8(StringView);
      88             : 
      89             : template <typename Interface>
      90             : auto toupper(const StringView & str) -> typename Interface::StringType;
      91             : 
      92             : template <typename Interface>
      93             : auto toupper(const WideStringView & str) -> typename Interface::WideStringType;
      94             : 
      95             : template <typename Interface>
      96             : auto tolower(const StringView & str) -> typename Interface::StringType;
      97             : 
      98             : template <typename Interface>
      99             : auto tolower(const WideStringView & str) -> typename Interface::WideStringType;
     100             : 
     101             : template <typename Interface>
     102             : auto totitle(const StringView & str) -> typename Interface::StringType;
     103             : 
     104             : template <typename Interface>
     105             : auto totitle(const WideStringView & str) -> typename Interface::WideStringType;
     106             : 
     107             : template <typename Interface>
     108             : auto urlencode(const StringView &data) -> typename Interface::StringType;
     109             : 
     110             : template <typename Storage>
     111             : void urldecode(Storage &, const StringView &str);
     112             : 
     113             : template <typename Interface>
     114             : auto urldecode(const StringView &data) -> typename Interface::StringType;
     115             : 
     116             : template <typename Interface>
     117             : auto toKoi8r(const WideStringView &data) -> typename Interface::StringType;
     118             : 
     119             : template <typename T>
     120             : void split(const StringView &str, const StringView &delim, T && callback);
     121             : 
     122             : template <typename Interface>
     123             : auto decodeHtml(const StringView &data) -> typename Interface::StringType;
     124             : 
     125             : template <typename Container>
     126       94175 : void apply(Container &c, const Callback<void(typename Container::value_type &)> &cb) {
     127      755925 :         for (auto &it : c) {
     128      661750 :                 cb(it);
     129             :         }
     130       94175 : }
     131             : 
     132             : // fast tolower for C locale
     133             : template <typename Container>
     134       94175 : void apply_tolower_c(Container &c) {
     135       94175 :         stappler::string::apply(c, [] (typename Container::value_type &ch) {
     136      661750 :                 ch = std::tolower(ch);
     137             :         });
     138       94175 : }
     139             : 
     140             : // fast toupper for C locale
     141             : template <typename Container>
     142             : void apply_toupper_c(Container &c) {
     143             :         stappler::string::apply(c, [] (typename Container::value_type &ch) {
     144             :                 ch = std::toupper(ch);
     145             :         });
     146             : }
     147             : 
     148             : template <typename Interface>
     149             : struct StringTraits : public Interface {
     150             :         using String = typename Interface::StringType;
     151             :         using WideString = typename Interface::WideStringType;
     152             :         using StringStream = typename Interface::StringStreamType;
     153             : 
     154             :         template <typename Value>
     155             :         using Vector = typename Interface::template VectorType<Value>;
     156             : 
     157             :         template <typename Value>
     158             :         using Set = typename Interface::template SetType<Value>;
     159             : 
     160             :         template <typename T>
     161             :         static void split(const String &str, const String &delim, T && callback);
     162             : 
     163             :         static String urlencode(const StringView &data);
     164             :         static String urldecode(const StringView &str);
     165             : 
     166             :         static WideString toUtf16(char32_t);
     167             :         static WideString toUtf16(const StringView &str);
     168             :         static WideString toUtf16Html(const StringView &str);
     169             :         static String toUtf8(char32_t c);
     170             :         static String toUtf8(char16_t c);
     171             :         static String toUtf8(const WideStringView &str);
     172             : 
     173             :         static String toKoi8r(const WideStringView &str);
     174             : 
     175             :         static WideString tolower(const WideStringView &str);
     176             :         static WideString toupper(const WideStringView &str);
     177             :         static WideString totitle(const WideStringView &str);
     178             : 
     179             :         static String tolower(const StringView &str);
     180             :         static String toupper(const StringView &str);
     181             :         static String totitle(const StringView &str);
     182             : 
     183             :         static String decodeHtml(const StringView &);
     184             : 
     185             :         static bool isUrlencodeChar(char c);
     186             : };
     187             : 
     188             : }
     189             : 
     190             : 
     191             : namespace STAPPLER_VERSIONIZED stappler::string {
     192             : 
     193             : using Sha256 = crypto::Sha256;
     194             : using Sha512 = crypto::Sha512;
     195             : 
     196             : /* Very simple and quick hasher, do NOT use it in collision-sensative cases */
     197         262 : inline uint32_t hash32(const StringView &key) { return hash::hash32(key.data(), uint32_t(key.size())); }
     198             : inline uint64_t hash64(const StringView &key) { return hash::hash64(key.data(), key.size()); }
     199             : 
     200             : /* default stdlib hash 32/64-bit, platform depended, unsigned variant (do NOT use for storage) */
     201             : template <typename StringType>
     202             : inline uint64_t stdlibHashUnsigned(const StringType &key) { std::hash<StringType> hasher; return hasher(key); }
     203             : 
     204             : /* default stdlib hash 32/64-bit, platform depended, signed variant, can be used for storage */
     205             : template <typename StringType>
     206             : inline int64_t stdlibHashSigned(const StringType &key) { return reinterpretValue<int64_t>(stdlibHashUnsigned(key)); }
     207             : 
     208             : }
     209             : 
     210             : 
     211             : namespace STAPPLER_VERSIONIZED stappler::base16 {
     212             : 
     213             : const char *charToHex(const char &c, bool upper = false);
     214             : uint8_t hexToChar(const char &c);
     215             : uint8_t hexToChar(const char &c, const char &d);
     216             : 
     217             : size_t encodeSize(size_t);
     218             : size_t decodeSize(size_t);
     219             : 
     220             : template <typename Interface>
     221             : auto encode(const CoderSource &source) -> typename Interface::StringType;
     222             : 
     223             : void encode(std::basic_ostream<char> &stream, const CoderSource &source);
     224             : void encode(const Callback<void(char)> &cb, const CoderSource &source);
     225             : size_t encode(char *, size_t bsize, const CoderSource &source);
     226             : 
     227             : template <typename Interface>
     228             : auto decode(const CoderSource &source) -> typename Interface::BytesType;
     229             : 
     230             : void decode(std::basic_ostream<char> &stream, const CoderSource &source);
     231             : void decode(const Callback<void(uint8_t)> &cb, const CoderSource &source);
     232             : size_t decode(uint8_t *, size_t bsize, const CoderSource &source);
     233             : 
     234             : }
     235             : 
     236             : 
     237             : namespace STAPPLER_VERSIONIZED stappler::base64 {
     238             : 
     239             : size_t encodeSize(size_t);
     240             : size_t decodeSize(size_t);
     241             : 
     242             : template <typename Interface>
     243             : auto encode(const CoderSource &source) -> typename Interface::StringType;
     244             : 
     245             : void encode(std::basic_ostream<char> &stream, const CoderSource &source);
     246             : void encode(const Callback<void(char)> &cb, const CoderSource &source);
     247             : size_t encode(char *, size_t bsize, const CoderSource &source);
     248             : 
     249             : 
     250             : template <typename Interface>
     251             : auto decode(const CoderSource &source) -> typename Interface::BytesType;
     252             : 
     253             : void decode(std::basic_ostream<char> &stream, const CoderSource &source);
     254             : void decode(const Callback<void(uint8_t)> &cb, const CoderSource &source);
     255             : size_t decode(uint8_t *, size_t bsize, const CoderSource &source);
     256             : 
     257             : }
     258             : 
     259             : 
     260             : namespace STAPPLER_VERSIONIZED stappler::base64url {
     261             : 
     262             : size_t encodeSize(size_t);
     263             : size_t decodeSize(size_t);
     264             : 
     265             : template <typename Interface>
     266             : auto encode(const CoderSource &source) -> typename Interface::StringType;
     267             : 
     268             : void encode(std::basic_ostream<char> &stream, const CoderSource &source);
     269             : void encode(const Callback<void(char)> &cb, const CoderSource &source);
     270             : size_t encode(char *, size_t bsize, const CoderSource &source);
     271             : 
     272             : 
     273             : template <typename Interface>
     274             : auto decode(const CoderSource &source) -> typename Interface::BytesType;
     275             : 
     276             : void decode(std::basic_ostream<char> &stream, const CoderSource &source);
     277             : void decode(const Callback<void(uint8_t)> &cb, const CoderSource &source);
     278             : size_t decode(uint8_t *, size_t bsize, const CoderSource &source);
     279             : 
     280             : }
     281             : 
     282             : 
     283             : namespace STAPPLER_VERSIONIZED stappler {
     284             : 
     285             : template<typename Container, typename StreamType>
     286             : inline void toStringStreamConcat(StreamType &stream, const Container &c) {
     287             :         for (auto &it : c) {
     288             :                 stream << it;
     289             :         }
     290             : }
     291             : 
     292             : template<typename Container, typename Sep, typename StreamType>
     293             : inline void toStringStreamConcat(StreamType &stream, const Container &c, const Sep &s) {
     294             :         bool b = false;
     295             :         for (auto &it : c) {
     296             :                 if (b) { stream << s; } else { b = true; }
     297             :                 stream << it;
     298             :         }
     299             : }
     300             : 
     301             : template<typename Container, typename StringType>
     302             : inline auto toStringConcat(const Container &c) -> StringType {
     303             :         typename traits::SelectStringStream<StringType>::Type stream;
     304             :         toStringStreamConcat(stream, c);
     305             :         return stream.str();
     306             : }
     307             : 
     308             : template<typename Container, typename Sep, typename StringType>
     309             : inline auto toStringConcat(const Container &c, const Sep &s) -> StringType {
     310             :         typename traits::SelectStringStream<StringType>::Type stream;
     311             :         toStringStreamConcat(stream, c, s);
     312             :         return stream.str();
     313             : }
     314             : 
     315             : }
     316             : 
     317             : 
     318             : namespace STAPPLER_VERSIONIZED stappler::string {
     319             : 
     320             : template <typename Interface>
     321         308 : auto toupper(const StringView & str) -> typename Interface::StringType {
     322         308 :         return StringTraits<Interface>::toupper(str);
     323             : }
     324             : 
     325             : template <typename Interface>
     326             : auto toupper(const WideStringView & str) -> typename Interface::WideStringType {
     327             :         return StringTraits<Interface>::toupper(str);
     328             : }
     329             : 
     330             : template <typename Interface>
     331       19425 : auto tolower(const StringView & str) -> typename Interface::StringType {
     332       19425 :         return StringTraits<Interface>::tolower(str);
     333             : }
     334             : 
     335             : template <typename Interface>
     336      111550 : auto tolower(const WideStringView & str) -> typename Interface::WideStringType {
     337      111550 :         return StringTraits<Interface>::tolower(str);
     338             : }
     339             : 
     340             : template <typename Interface>
     341          25 : auto totitle(const StringView & str) -> typename Interface::StringType {
     342          25 :         return StringTraits<Interface>::totitle(str);
     343             : }
     344             : 
     345             : template <typename Interface>
     346             : auto totitle(const WideStringView & str) -> typename Interface::WideStringType {
     347             :         return StringTraits<Interface>::totitle(str);
     348             : }
     349             : 
     350             : template <typename Interface>
     351             : inline auto urlencode(const StringView &data) -> typename Interface::StringType {
     352             :         return StringTraits<Interface>::urlencode(data);
     353             : }
     354             : 
     355             : template <typename Interface>
     356        6875 : inline auto urldecode(const StringView &data) -> typename Interface::StringType {
     357        6875 :         return StringTraits<Interface>::urldecode(data);
     358             : }
     359             : 
     360             : template <typename Interface>
     361      122839 : inline auto toUtf16(const StringView &data) -> typename Interface::WideStringType {
     362      122839 :         return StringTraits<Interface>::toUtf16(data);
     363             : }
     364             : 
     365             : template <typename Interface>
     366         945 : inline auto toUtf16(char32_t ch) -> typename Interface::WideStringType {
     367         945 :         return StringTraits<Interface>::toUtf16(ch);
     368             : }
     369             : 
     370             : template <typename Interface>
     371          75 : inline auto toUtf16Html(const StringView &data) -> typename Interface::WideStringType {
     372          75 :         return StringTraits<Interface>::toUtf16Html(data);
     373             : }
     374             : 
     375             : template <typename Interface>
     376      112024 : inline auto toUtf8(const WideStringView &data) -> typename Interface::StringType {
     377      112024 :         return StringTraits<Interface>::toUtf8(data);
     378             : }
     379             : 
     380             : template <typename Interface>
     381          25 : inline auto toUtf8(char16_t c) -> typename Interface::StringType {
     382          25 :         return StringTraits<Interface>::toUtf8(c);
     383             : }
     384             : 
     385             : template <typename Interface>
     386          25 : inline auto toUtf8(char32_t c) -> typename Interface::StringType {
     387          25 :         return StringTraits<Interface>::toUtf8(c);
     388             : }
     389             : 
     390             : template <typename Interface>
     391          50 : inline auto toKoi8r(const WideStringView &data) -> typename Interface::StringType {
     392          50 :         return StringTraits<Interface>::toKoi8r(data);
     393             : }
     394             : 
     395             : template <typename Interface>
     396             : inline auto decodeHtml(const StringView &data) -> typename Interface::StringType {
     397             :         return StringTraits<Interface>::decodeHtml(data);
     398             : }
     399             : 
     400             : template <typename T>
     401        3200 : inline void split(const StringView &str, const StringView &delim, T && callback) {
     402        3200 :         StringView r(str);
     403        6500 :         while (!r.empty()) {
     404        3300 :                 auto w = r.readUntilString(delim);
     405        3300 :                 if (r.is(delim)) {
     406         100 :                         r += delim.size();
     407             :                 }
     408        3300 :                 if (!w.empty()) {
     409        3300 :                         callback(w);
     410             :                 }
     411             :         }
     412        3200 : }
     413             : 
     414             : template <typename Interface>
     415             : template <typename T>
     416             : void StringTraits<Interface>::split(const String &str, const String &delim, T && callback) {
     417             :         size_t start = 0;
     418             :         size_t pos = 0;
     419             :         for (pos = str.find(delim, start); pos != String::npos; start = pos + delim.length(), pos = str.find(delim, start)) {
     420             :                 if (pos != start) {
     421             :                         callback(CharReaderBase(str.data() + start, pos - start));
     422             :                 }
     423             :         }
     424             :         if (start < str.length()) {
     425             :                 callback(CharReaderBase(str.data() + start, str.size() - start));
     426             :         }
     427             : }
     428             : 
     429             : template <typename Interface>
     430             : auto StringTraits<Interface>::urlencode(const StringView &data) -> String {
     431             :         String ret; ret.reserve(data.size() * 2);
     432             :         for (auto &c : data) {
     433             :         if (isUrlencodeChar(c)) {
     434             :                 ret.push_back('%');
     435             :                 ret.append(base16::charToHex(c, true), 2);
     436             :         } else {
     437             :                 ret.push_back(c);
     438             :         }
     439             :         }
     440             :         return ret;
     441             : }
     442             : 
     443             : template <typename Storage>
     444       12025 : inline void urldecode(Storage &storage, const StringView &str) {
     445             :         using Value = typename Storage::value_type *;
     446             : 
     447       12025 :         storage.reserve(str.size());
     448             : 
     449       12025 :         StringView r(str);
     450       23800 :         while (!r.empty()) {
     451       11775 :                 StringView tmp = r.readUntil<StringView::Chars<'%'>>();
     452       11775 :                 storage.insert(storage.end(), Value(tmp.data()), Value(tmp.data() + tmp.size()));
     453             : 
     454       11775 :                 if (r.is('%') && r > 2) {
     455         700 :                         StringView hex(r.data() + 1, 2);
     456         700 :                         hex.skipChars<StringView::CharGroup<CharGroupId::Hexadecimial>>();
     457         700 :                         if (hex.empty()) {
     458         700 :                                 storage.push_back(base16::hexToChar(r[1], r[2]));
     459             :                         } else {
     460           0 :                                 storage.insert(storage.end(), Value(r.data()), Value(r.data() + 3));
     461             :                         }
     462         700 :                         r += 3;
     463       11075 :                 } else if (!r.empty()) {
     464           0 :                         storage.insert(storage.end(), Value(r.data()), Value(r.data() + r.size()));
     465           0 :                         r.clear();
     466             :                 }
     467             :         }
     468       12025 : }
     469             : 
     470             : template <typename Interface>
     471        6875 : auto StringTraits<Interface>::urldecode(const StringView &str) -> String {
     472        6875 :         String ret;
     473        6875 :         string::urldecode(ret, str);
     474        6875 :         return ret;
     475           0 : }
     476             : 
     477             : template <typename Interface>
     478         945 : auto StringTraits<Interface>::toUtf16(char32_t ch) -> WideString {
     479         945 :         const auto size = string::getUtf16Length(ch);
     480         945 :         WideString utf16_str; utf16_str.reserve(size);
     481             : 
     482         945 :         unicode::utf16Encode(utf16_str, ch);
     483             : 
     484         945 :     return utf16_str;
     485           0 : }
     486             : 
     487             : template <typename Interface>
     488      122839 : auto StringTraits<Interface>::toUtf16(const StringView &utf8_str) -> WideString {
     489      122839 :         const auto size = string::getUtf16Length(utf8_str);
     490      122839 :         WideString utf16_str; utf16_str.reserve(size);
     491             : 
     492      122839 :         uint8_t offset = 0;
     493      122839 :         auto ptr = utf8_str.data();
     494      122839 :         auto end = ptr + utf8_str.size();
     495     1201173 :         while (ptr < end) {
     496     1078334 :                 auto c = unicode::utf8Decode32(ptr, offset);
     497     1078334 :                 unicode::utf16Encode(utf16_str, c);
     498     1078334 :                 ptr += offset;
     499             :         }
     500             : 
     501      245678 :     return utf16_str;
     502           0 : }
     503             : 
     504             : template <typename Interface>
     505          75 : auto StringTraits<Interface>::toUtf16Html(const StringView &utf8_str) -> WideString {
     506          75 :         const auto size = string::getUtf16HtmlLength(utf8_str);
     507          75 :         WideString utf16_str; utf16_str.reserve(size);
     508             : 
     509          75 :         uint8_t offset = 0;
     510          75 :         auto ptr = utf8_str.data();
     511          75 :         auto end = ptr + utf8_str.size();
     512        1900 :         while (ptr < end) {
     513        1825 :                 auto c = unicode::utf8HtmlDecode32(ptr, offset);
     514        1825 :                 unicode::utf16Encode(utf16_str, c);
     515        1825 :                 ptr += offset;
     516             :         }
     517             : 
     518         150 :         return utf16_str;
     519           0 : }
     520             : 
     521             : template <typename Interface>
     522      112024 : auto StringTraits<Interface>::toUtf8(const WideStringView &str) -> String {
     523      112024 :         const auto size = string::getUtf8Length(str);
     524      112024 :         String ret; ret.reserve(size);
     525             : 
     526             :         uint8_t offset;
     527      112024 :         auto ptr = str.data();
     528      112024 :         auto end = ptr + str.size();
     529      784272 :         while (ptr < end) {
     530      672248 :                 auto c = unicode::utf16Decode32(ptr, offset);
     531      672248 :                 unicode::utf8Encode(ret, c);
     532      672248 :                 ptr += offset;
     533             :         }
     534             : 
     535      224048 :         return ret;
     536           0 : }
     537             : 
     538             : template <typename Interface>
     539          25 : auto StringTraits<Interface>::toUtf8(char16_t c) -> String {
     540          25 :         String ret; ret.reserve(unicode::utf8EncodeLength(c));
     541          25 :         unicode::utf8Encode(ret, c);
     542          25 :         return ret;
     543           0 : }
     544             : 
     545             : template <typename Interface>
     546          25 : auto StringTraits<Interface>::toUtf8(char32_t c) -> String {
     547          25 :         String ret; ret.reserve(unicode::utf8EncodeLength(c));
     548          25 :         unicode::utf8Encode(ret, c);
     549          25 :         return ret;
     550           0 : }
     551             : 
     552             : template <typename Interface>
     553          50 : auto StringTraits<Interface>::toKoi8r(const WideStringView &str) -> String {
     554          50 :         String ret; ret.reserve(str.size());
     555          50 :         auto ptr = str.data();
     556          50 :         auto end = ptr + str.size();
     557        2050 :         while (ptr < end) {
     558        2000 :                 ret.push_back(charToKoi8r(*ptr++));
     559             :         }
     560          50 :         return ret;
     561           0 : }
     562             : 
     563             : template <typename Interface>
     564      111550 : auto StringTraits<Interface>::tolower(const WideStringView &str) -> WideString {
     565      111550 :         return platform::tolower<Interface>(str);
     566             : }
     567             : 
     568             : template <typename Interface>
     569             : auto StringTraits<Interface>::toupper(const WideStringView &str) -> WideString {
     570             :         return platform::toupper<Interface>(str);
     571             : }
     572             : 
     573             : template <typename Interface>
     574             : auto StringTraits<Interface>::totitle(const WideStringView &str) -> WideString {
     575             :         return platform::totitle<Interface>(str);
     576             : }
     577             : 
     578             : template <typename Interface>
     579       19481 : auto StringTraits<Interface>::tolower(const StringView &str) -> String {
     580       19481 :         return platform::tolower<Interface>(str);
     581             : }
     582             : 
     583             : template <typename Interface>
     584         308 : auto StringTraits<Interface>::toupper(const StringView &str) -> String {
     585         308 :         return platform::toupper<Interface>(str);
     586             : }
     587             : 
     588             : template <typename Interface>
     589          25 : auto StringTraits<Interface>::totitle(const StringView &str) -> String {
     590          25 :         return platform::totitle<Interface>(str);
     591             : }
     592             : 
     593             : template <typename Interface>
     594             : auto StringTraits<Interface>::decodeHtml(const StringView &utf8_str) -> String {
     595             :         const auto size = string::getUtf8HtmlLength(utf8_str);
     596             :         String result_str; result_str.reserve(size);
     597             : 
     598             :         uint8_t offset = 0;
     599             :         auto ptr = utf8_str.data();
     600             :         auto end = ptr + utf8_str.size();
     601             :         while (ptr < end) {
     602             :                 if (*ptr == '&') {
     603             :                         auto c = unicode::utf8HtmlDecode32(ptr, offset);
     604             :                         unicode::utf8Encode(result_str, c);
     605             :                         ptr += offset;
     606             :                 } else {
     607             :                         result_str.emplace_back(*ptr);
     608             :                         ++ ptr;
     609             :                 }
     610             :         }
     611             : 
     612             :         return result_str;
     613             : }
     614             : 
     615             : template <typename Interface>
     616             : bool StringTraits<Interface>::isUrlencodeChar(char c) {
     617             :         if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')
     618             :                         || c == '-' || c == '_' || c == '~' || c == '.') {
     619             :                 return false;
     620             :         } else {
     621             :                 return true;
     622             :         }
     623             : }
     624             : 
     625             : }
     626             : 
     627             : namespace STAPPLER_VERSIONIZED stappler::base64 {
     628             : 
     629             : auto __encode_pool(const CoderSource &source) -> typename memory::PoolInterface::StringType;
     630             : auto __encode_std(const CoderSource &source) -> typename memory::StandartInterface::StringType;
     631             : 
     632             : auto __decode_pool(const CoderSource &source) -> typename memory::PoolInterface::BytesType;
     633             : auto __decode_std(const CoderSource &source) -> typename memory::StandartInterface::BytesType;
     634             : 
     635             : template <>
     636        1125 : inline auto decode<memory::PoolInterface>(const CoderSource &source) -> typename memory::PoolInterface::BytesType {
     637        1125 :         return __decode_pool(source);
     638             : }
     639             : 
     640             : template <>
     641        1575 : inline auto decode<memory::StandartInterface>(const CoderSource &source) -> typename memory::StandartInterface::BytesType {
     642        1575 :         return __decode_std(source);
     643             : }
     644             : 
     645             : }
     646             : 
     647             : namespace STAPPLER_VERSIONIZED stappler::base64url {
     648             : 
     649        1850 : inline size_t encodeSize(size_t l) { return base64::encodeSize(l); }
     650             : inline size_t decodeSize(size_t l) { return base64::decodeSize(l); }
     651             : 
     652             : auto __encode_pool(const CoderSource &source) -> typename memory::PoolInterface::StringType;
     653             : auto __encode_std(const CoderSource &source) -> typename memory::StandartInterface::StringType;
     654             : 
     655             : template <typename Interface>
     656         300 : inline auto decode(const CoderSource &source) -> typename Interface::BytesType {
     657         300 :         return base64::decode<Interface>(source);
     658             : }
     659             : 
     660          25 : inline void decode(std::basic_ostream<char> &stream, const CoderSource &source) {
     661          25 :         base64::decode(stream, source);
     662          25 : }
     663             : 
     664             : inline void decode(const Callback<void(uint8_t)> &cb, const CoderSource &source) {
     665             :         base64::decode(cb, source);
     666             : }
     667             : 
     668          50 : inline size_t decode(uint8_t *buf, size_t bsize, const CoderSource &source) {
     669          50 :         return base64::decode(buf, bsize, source);;
     670             : }
     671             : 
     672             : }
     673             : 
     674             : 
     675             : namespace STAPPLER_VERSIONIZED stappler::mem_pool {
     676             : 
     677             : using String = stappler::memory::string;
     678             : using WideString = stappler::memory::u16string;
     679             : using StringStream = stappler::memory::ostringstream;
     680             : using Interface = stappler::memory::PoolInterface;
     681             : 
     682             : template <typename... Args>
     683       45528 : inline String toString(Args && ... args) {
     684       45528 :         return string::toString<Interface>(std::forward<Args>(args)...);
     685             : }
     686             : 
     687             : }
     688             : 
     689             : namespace STAPPLER_VERSIONIZED stappler::mem_std {
     690             : 
     691             : using String = std::string;
     692             : using WideString = std::u16string;
     693             : using StringStream = std::stringstream;
     694             : using Interface = stappler::memory::StandartInterface;
     695             : 
     696             : template <typename... Args>
     697     1160037 : inline String toString(Args && ... args) {
     698     1160037 :         return string::toString<Interface>(std::forward<Args>(args)...);
     699             : }
     700             : 
     701             : }
     702             : 
     703             : #endif /* STAPPLER_CORE_STRING_SPSTRING_H_ */

Generated by: LCOV version 1.14