LCOV - code coverage report
Current view: top level - core/core/string - SPBytesReader.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 52 55 94.5 %
Date: 2024-05-12 00:16:13 Functions: 48 49 98.0 %

          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_SPBYTESREADER_H_
      25             : #define STAPPLER_CORE_STRING_SPBYTESREADER_H_
      26             : 
      27             : #include "SPCharGroup.h"
      28             : 
      29             : namespace STAPPLER_VERSIONIZED stappler {
      30             : 
      31             : template <typename _CharType>
      32             : class BytesReader {
      33             : public:
      34             :         using CharType = _CharType;
      35             : 
      36             :         template <CharType ... Args>
      37             :         using Chars = chars::Chars<CharType, Args...>;
      38             : 
      39             :         template <CharType First, CharType Last>
      40             :         using Range = chars::Range<CharType, First, Last>;
      41             : 
      42             :         template <CharGroupId Group>
      43             :         using CharGroup = chars::CharGroup<CharType, Group>;
      44             : 
      45             :         template <typename ... Args>
      46             :         using Compose = chars::Compose<CharType, Args ...>;
      47             : 
      48     1289230 :         constexpr BytesReader() : ptr(nullptr), len(0) { }
      49  1074870694 :         constexpr BytesReader(const CharType *p, size_t l) : ptr(p), len(l) { }
      50             : 
      51             :         BytesReader & set(const CharType *p, size_t l) { ptr = p; len = l; return *this; }
      52             : 
      53    16708969 :         void offset(size_t l) { if (l > len) { len = 0; } else { ptr += l; len -= l; } }
      54             : 
      55      112950 :         bool equals(const CharType *d, size_t l) const { return (l == len && memcmp(ptr, d, l * sizeof(CharType)) == 0); }
      56      105225 :         bool equals(const CharType *d) const { return equals(d, std::char_traits<CharType>::length(d)); }
      57             : 
      58     1856277 :         bool prefix(const CharType *d, size_t l) const { return (l <= len && memcmp(ptr, d, l * sizeof(CharType)) == 0); }
      59             : 
      60       38325 :         bool starts_with(const BytesReader<CharType> &str) const { return prefix(str.data(), str.size()); }
      61        1338 :         bool starts_with(const CharType *d, size_t l) const { return prefix(d, l); }
      62      873080 :         bool starts_with(const CharType *d) const { return prefix(d, std::char_traits<CharType>::length(d)); }
      63             : 
      64             :         bool ends_with(const BytesReader<CharType> &str) const { return ends_with(str.data(), str.size()); }
      65        7800 :         bool ends_with(const CharType *d, size_t l) const { return (l <= len && memcmp(ptr + (len - l), d, l * sizeof(CharType)) == 0); }
      66        7800 :         bool ends_with(const CharType *d) const { return ends_with(d, std::char_traits<CharType>::length(d)); }
      67             : 
      68  1214520662 :         constexpr const CharType *data() const { return ptr; }
      69             : 
      70  1326160082 :         constexpr size_t size() const { return len; }
      71             : 
      72             :         size_t find(const CharType *s, size_t pos, size_t n) const;
      73             :         size_t find(CharType c, size_t pos = 0) const;
      74             : 
      75             :         size_t rfind(const CharType *s, size_t pos, size_t n) const;
      76             :         size_t rfind(CharType c, size_t pos = maxOf<size_t>()) const;
      77             : 
      78             :         size_t find(const BytesReader<CharType> &str, size_t pos = 0) const { return this->find(str.data(), pos, str.size()); }
      79        3338 :         size_t find(const CharType *s, size_t pos = 0) const { return this->find(s, pos, std::char_traits<CharType>::length(s)); }
      80             : 
      81             :         size_t rfind(const BytesReader<CharType> &str, size_t pos = maxOf<size_t>()) const { return this->rfind(str.data(), pos, str.size()); }
      82             :         size_t rfind(const CharType *s, size_t pos = maxOf<size_t>()) const { return this->rfind(s, pos, std::char_traits<CharType>::length(s)); }
      83             : 
      84       41075 :         bool is(const CharType &c) const { return len > 0 && *ptr == c; };
      85             : 
      86         700 :         bool operator > (const size_t &val) const { return len > val; }
      87       32800 :         bool operator >= (const size_t &val) const { return len >= val; }
      88             :         bool operator < (const size_t &val) const { return len < val; }
      89             :         bool operator <= (const size_t &val) const { return len <= val; }
      90             : 
      91       91511 :         const CharType & front() const { return *ptr; }
      92       56175 :         const CharType & back() const { return ptr[len - 1]; }
      93             : 
      94       40669 :         const CharType & at(const size_t &s) const { return ptr[s]; }
      95    76701793 :         const CharType & operator[] (const size_t &s) const { return ptr[s]; }
      96       11020 :         const CharType & operator * () const { return *ptr; }
      97             : 
      98       30650 :         void clear() { len = 0; }
      99   485849830 :         bool empty() const { return len == 0 || !ptr; }
     100             : 
     101      115624 :         bool terminated() const { return ptr[len] == 0; }
     102             : 
     103             : protected:
     104             :         const CharType *ptr;
     105             :         size_t len;
     106             : };
     107             : 
     108             : template <typename CharType> inline size_t
     109        3338 : BytesReader<CharType>::find(const CharType * __s, size_t __pos, size_t __n) const {
     110             :         using traits_type = std::char_traits<CharType>;
     111        3338 :         const size_t __size = this->size();
     112        3338 :         const CharType* __data = data();
     113             : 
     114        3338 :         if (__n == 0) {
     115           0 :                 return __pos <= __size ? __pos : maxOf<size_t>();
     116        3338 :         } else if (__n <= __size) {
     117       13857 :                 for (; __pos <= __size - __n; ++__pos)
     118       13619 :                 if (traits_type::eq(__data[__pos], __s[0])
     119       13619 :                                 && traits_type::compare(__data + __pos + 1,
     120             :                                                 __s + 1, __n - 1) == 0)
     121           0 :                 return __pos;
     122             :         }
     123        3338 :         return maxOf<size_t>();
     124             : }
     125             : 
     126             : template <typename CharType> inline size_t
     127       10475 : BytesReader<CharType>::find(CharType __c, size_t __pos) const {
     128             :         using traits_type = std::char_traits<CharType>;
     129       10475 :         size_t __ret = maxOf<size_t>();
     130       10475 :         const size_t __size = this->size();
     131       10475 :         if (__pos < __size) {
     132       10475 :                 const CharType * __data = data();
     133       10475 :                 const size_t __n = __size - __pos;
     134       10475 :                 const CharType * __p = traits_type::find(__data + __pos, __n, __c);
     135       10475 :                 if (__p)
     136       10475 :                         __ret = __p - __data;
     137             :         }
     138       10475 :         return __ret;
     139             : }
     140             : 
     141             : template <typename CharType> inline size_t
     142             : BytesReader<CharType>::rfind(const CharType* __s, size_t __pos, size_t __n) const {
     143             :         using traits_type = std::char_traits<CharType>;
     144             :         const size_t __size = this->size();
     145             :         if (__n <= __size) {
     146             :                 __pos = min(size_t(__size - __n), __pos);
     147             :                 const CharType* __data = data();
     148             :                 do {
     149             :                         if (traits_type::compare(__data + __pos, __s, __n) == 0)
     150             :                                 return __pos;
     151             :                 }
     152             :                 while (__pos-- > 0);
     153             :         }
     154             :         return maxOf<size_t>();
     155             : }
     156             : 
     157             : template <typename CharType> inline size_t
     158       45775 : BytesReader<CharType>::rfind(CharType __c, size_t __pos) const {
     159             :         using traits_type = std::char_traits<CharType>;
     160       45775 :         size_t __size = this->size();
     161       45775 :         if (__size) {
     162       45775 :                 if (--__size > __pos)
     163           0 :                         __size = __pos;
     164      444654 :                 for (++__size; __size-- > 0; )
     165      444629 :                         if (traits_type::eq(data()[__size], __c))
     166       45750 :                 return __size;
     167             :         }
     168          25 :         return maxOf<size_t>();
     169             : }
     170             : 
     171             : }
     172             : 
     173             : #endif /* STAPPLER_CORE_STRING_SPBYTESREADER_H_ */

Generated by: LCOV version 1.14