diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/fxcrt/bytestring_unittest.cpp | 99 | ||||
-rw-r--r-- | core/fxcrt/string_view_template.h | 142 |
2 files changed, 129 insertions, 112 deletions
diff --git a/core/fxcrt/bytestring_unittest.cpp b/core/fxcrt/bytestring_unittest.cpp index ce1512b4cf..74e52db69a 100644 --- a/core/fxcrt/bytestring_unittest.cpp +++ b/core/fxcrt/bytestring_unittest.cpp @@ -9,6 +9,7 @@ #include "core/fxcrt/fx_string.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/base/span.h" #include "third_party/base/stl_util.h" namespace fxcrt { @@ -349,45 +350,6 @@ TEST(ByteString, OperatorNE) { EXPECT_TRUE(c_string3 != byte_string); } -TEST(ByteStringView, Null) { - ByteStringView null_string; - EXPECT_FALSE(null_string.raw_str()); - EXPECT_EQ(0u, null_string.GetLength()); - EXPECT_TRUE(null_string.IsEmpty()); - - ByteStringView another_null_string; - EXPECT_EQ(null_string, another_null_string); - - ByteStringView copied_null_string(null_string); - EXPECT_FALSE(copied_null_string.raw_str()); - EXPECT_EQ(0u, copied_null_string.GetLength()); - EXPECT_TRUE(copied_null_string.IsEmpty()); - EXPECT_EQ(null_string, copied_null_string); - - ByteStringView empty_string(""); // Pointer to NUL, not NULL pointer. - EXPECT_TRUE(empty_string.raw_str()); - EXPECT_EQ(0u, empty_string.GetLength()); - EXPECT_TRUE(empty_string.IsEmpty()); - EXPECT_EQ(null_string, empty_string); - - ByteStringView assigned_null_string("initially not nullptr"); - assigned_null_string = null_string; - EXPECT_FALSE(assigned_null_string.raw_str()); - EXPECT_EQ(0u, assigned_null_string.GetLength()); - EXPECT_TRUE(assigned_null_string.IsEmpty()); - EXPECT_EQ(null_string, assigned_null_string); - - ByteStringView assigned_nullptr_string("initially not nullptr"); - assigned_nullptr_string = nullptr; - EXPECT_FALSE(assigned_nullptr_string.raw_str()); - EXPECT_EQ(0u, assigned_nullptr_string.GetLength()); - EXPECT_TRUE(assigned_nullptr_string.IsEmpty()); - EXPECT_EQ(null_string, assigned_nullptr_string); - - ByteStringView non_null_string("a"); - EXPECT_NE(null_string, non_null_string); -} - TEST(ByteString, Concat) { ByteString fred; fred.Concat("FRED", 4); @@ -1001,16 +963,71 @@ TEST(ByteString, MultiCharReverseIterator) { EXPECT_TRUE(iter == multi_str.rbegin()); } +TEST(ByteStringView, Null) { + ByteStringView null_string; + EXPECT_FALSE(null_string.raw_str()); + EXPECT_EQ(0u, null_string.GetLength()); + EXPECT_TRUE(null_string.IsEmpty()); + + ByteStringView another_null_string; + EXPECT_EQ(null_string, another_null_string); + + ByteStringView copied_null_string(null_string); + EXPECT_FALSE(copied_null_string.raw_str()); + EXPECT_EQ(0u, copied_null_string.GetLength()); + EXPECT_TRUE(copied_null_string.IsEmpty()); + EXPECT_EQ(null_string, copied_null_string); + + ByteStringView span_null_string = pdfium::span<const uint8_t>(); + EXPECT_FALSE(span_null_string.raw_str()); + EXPECT_EQ(0u, span_null_string.GetLength()); + EXPECT_TRUE(span_null_string.IsEmpty()); + EXPECT_EQ(null_string, span_null_string); + + ByteStringView empty_string(""); // Pointer to NUL, not NULL pointer. + EXPECT_TRUE(empty_string.raw_str()); + EXPECT_EQ(0u, empty_string.GetLength()); + EXPECT_TRUE(empty_string.IsEmpty()); + EXPECT_EQ(null_string, empty_string); + + ByteStringView assigned_null_string("initially not nullptr"); + assigned_null_string = null_string; + EXPECT_FALSE(assigned_null_string.raw_str()); + EXPECT_EQ(0u, assigned_null_string.GetLength()); + EXPECT_TRUE(assigned_null_string.IsEmpty()); + EXPECT_EQ(null_string, assigned_null_string); + + ByteStringView assigned_nullptr_string("initially not nullptr"); + assigned_nullptr_string = nullptr; + EXPECT_FALSE(assigned_nullptr_string.raw_str()); + EXPECT_EQ(0u, assigned_nullptr_string.GetLength()); + EXPECT_TRUE(assigned_nullptr_string.IsEmpty()); + EXPECT_EQ(null_string, assigned_nullptr_string); + + ByteStringView assigned_span_null_string("initially not null span"); + assigned_span_null_string = pdfium::span<const uint8_t>(); + EXPECT_FALSE(assigned_span_null_string.raw_str()); + EXPECT_EQ(0u, assigned_span_null_string.GetLength()); + EXPECT_TRUE(assigned_span_null_string.IsEmpty()); + EXPECT_EQ(null_string, assigned_span_null_string); + + ByteStringView non_null_string("a"); + EXPECT_NE(null_string, non_null_string); +} + TEST(ByteStringView, NotNull) { ByteStringView string3("abc"); ByteStringView string6("abcdef"); ByteStringView alternate_string3("abcdef", 3); + ByteStringView span_string4( + pdfium::span<const uint8_t>(reinterpret_cast<const uint8_t*>("abcd"), 4)); ByteStringView embedded_nul_string7("abc\0def", 7); ByteStringView illegal_string7("abcdef", 7); EXPECT_EQ(3u, string3.GetLength()); EXPECT_EQ(6u, string6.GetLength()); EXPECT_EQ(3u, alternate_string3.GetLength()); + EXPECT_EQ(4u, span_string4.GetLength()); EXPECT_EQ(7u, embedded_nul_string7.GetLength()); EXPECT_EQ(7u, illegal_string7.GetLength()); @@ -1296,6 +1313,10 @@ TEST(ByteStringView, OperatorEQ) { EXPECT_FALSE(c_string1 == byte_string_c); EXPECT_FALSE(c_string2 == byte_string_c); EXPECT_FALSE(c_string3 == byte_string_c); + + pdfium::span<const uint8_t> span5(reinterpret_cast<const uint8_t*>("hello"), + 5); + EXPECT_EQ(byte_string_c.span(), span5); } TEST(ByteStringView, OperatorNE) { diff --git a/core/fxcrt/string_view_template.h b/core/fxcrt/string_view_template.h index 1e436d3978..05694cf244 100644 --- a/core/fxcrt/string_view_template.h +++ b/core/fxcrt/string_view_template.h @@ -16,6 +16,7 @@ #include "core/fxcrt/fx_system.h" #include "core/fxcrt/unowned_ptr.h" #include "third_party/base/optional.h" +#include "third_party/base/span.h" #include "third_party/base/stl_util.h" namespace fxcrt { @@ -31,63 +32,63 @@ class StringViewTemplate { using const_iterator = const CharType*; using const_reverse_iterator = std::reverse_iterator<const_iterator>; - StringViewTemplate() : m_Ptr(nullptr), m_Length(0) {} + constexpr StringViewTemplate() noexcept = default; + constexpr StringViewTemplate(const StringViewTemplate& src) noexcept = + default; // Deliberately implicit to avoid calling on every string literal. // NOLINTNEXTLINE(runtime/explicit) - StringViewTemplate(const CharType* ptr) - : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)), - m_Length(ptr ? FXSYS_len(ptr) : 0) {} + StringViewTemplate(const CharType* ptr) noexcept + : m_Span(reinterpret_cast<const UnsignedType*>(ptr), + ptr ? FXSYS_len(ptr) : 0) {} - StringViewTemplate(const CharType* ptr, size_t len) - : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)), m_Length(len) {} + constexpr StringViewTemplate(const CharType* ptr, size_t len) noexcept + : m_Span(reinterpret_cast<const UnsignedType*>(ptr), len) {} + + explicit constexpr StringViewTemplate( + const pdfium::span<CharType>& other) noexcept + : m_Span(reinterpret_cast<const UnsignedType*>(other.data()), + other.size()) {} template <typename U = UnsignedType> - StringViewTemplate( + constexpr StringViewTemplate( const UnsignedType* ptr, size_t size, - typename std::enable_if<!std::is_same<U, CharType>::value>::type* = 0) - : m_Ptr(ptr), m_Length(size) {} + typename std::enable_if<!std::is_same<U, CharType>::value>::type* = + 0) noexcept + : m_Span(ptr, size) {} + + template <typename U = UnsignedType> + StringViewTemplate( + const pdfium::span<U> other, + typename std::enable_if<!std::is_same<U, CharType>::value>::type* = + 0) noexcept + : m_Span(other) {} // Deliberately implicit to avoid calling on every string literal. // |ch| must be an lvalue that outlives the StringViewTemplate. // NOLINTNEXTLINE(runtime/explicit) - StringViewTemplate(CharType& ch) { - m_Ptr = reinterpret_cast<const UnsignedType*>(&ch); - m_Length = 1; - } - - StringViewTemplate(const StringViewTemplate& src) { - m_Ptr = src.m_Ptr; - m_Length = src.m_Length; - } + constexpr StringViewTemplate(CharType& ch) noexcept + : m_Span(reinterpret_cast<const UnsignedType*>(&ch), 1) {} // Any changes to |vec| invalidate the string. - explicit StringViewTemplate(const std::vector<UnsignedType>& vec) { - m_Length = vec.size(); - m_Ptr = m_Length ? vec.data() : nullptr; - } + explicit StringViewTemplate(const std::vector<UnsignedType>& vec) noexcept + : m_Span(vec.size() ? vec.data() : nullptr, vec.size()) {} StringViewTemplate& operator=(const CharType* src) { - m_Ptr = reinterpret_cast<const UnsignedType*>(src); - m_Length = src ? FXSYS_len(src) : 0; + m_Span = pdfium::span<const UnsignedType>( + reinterpret_cast<const UnsignedType*>(src), src ? FXSYS_len(src) : 0); return *this; } - StringViewTemplate& operator=(const StringViewTemplate& src) { - m_Ptr = src.m_Ptr; - m_Length = src.m_Length; - return *this; - } + StringViewTemplate& operator=(const StringViewTemplate& src) = default; const_iterator begin() const { - return reinterpret_cast<const CharType*>(m_Ptr.Get()); + return reinterpret_cast<const_iterator>(m_Span.begin()); } const_iterator end() const { - return m_Ptr ? reinterpret_cast<const CharType*>(m_Ptr.Get()) + m_Length - : nullptr; + return reinterpret_cast<const_iterator>(m_Span.end()); } - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } @@ -95,16 +96,12 @@ class StringViewTemplate { return const_reverse_iterator(begin()); } - bool operator==(const CharType* ptr) const { - return FXSYS_len(ptr) == m_Length && - FXSYS_cmp(ptr, reinterpret_cast<const CharType*>(m_Ptr.Get()), - m_Length) == 0; - } bool operator==(const StringViewTemplate& other) const { - return other.m_Length == m_Length && - FXSYS_cmp(reinterpret_cast<const CharType*>(other.m_Ptr.Get()), - reinterpret_cast<const CharType*>(m_Ptr.Get()), - m_Length) == 0; + return m_Span == other.m_Span; + } + bool operator==(const CharType* ptr) const { + StringViewTemplate other(ptr); + return *this == other; } bool operator!=(const CharType* ptr) const { return !(*this == ptr); } bool operator!=(const StringViewTemplate& other) const { @@ -112,54 +109,52 @@ class StringViewTemplate { } uint32_t GetID() const { - if (m_Length == 0) + if (m_Span.size() == 0) return 0; uint32_t strid = 0; - size_t size = std::min(static_cast<size_t>(4), m_Length); + size_t size = std::min(static_cast<size_t>(4), m_Span.size()); for (size_t i = 0; i < size; i++) - strid = strid * 256 + m_Ptr.Get()[i]; + strid = strid * 256 + m_Span[i]; return strid << ((4 - size) * 8); } - const UnsignedType* raw_str() const { return m_Ptr.Get(); } + pdfium::span<const UnsignedType> span() const { return m_Span; } + const UnsignedType* raw_str() const { return m_Span.data(); } const CharType* unterminated_c_str() const { - return reinterpret_cast<const CharType*>(m_Ptr.Get()); + return reinterpret_cast<const CharType*>(m_Span.data()); } - size_t GetLength() const { return m_Length; } - bool IsEmpty() const { return m_Length == 0; } - bool IsValidIndex(size_t index) const { return index < GetLength(); } - bool IsValidLength(size_t length) const { return length <= GetLength(); } + size_t GetLength() const { return m_Span.size(); } + bool IsEmpty() const { return m_Span.empty(); } + bool IsValidIndex(size_t index) const { return index < m_Span.size(); } + bool IsValidLength(size_t length) const { return length <= m_Span.size(); } const UnsignedType& operator[](const size_t index) const { - ASSERT(IsValidIndex(index)); - return m_Ptr.Get()[index]; + return m_Span[index]; } - UnsignedType First() const { return GetLength() ? (*this)[0] : 0; } - + UnsignedType First() const { return m_Span.size() ? m_Span[0] : 0; } UnsignedType Last() const { - return GetLength() ? (*this)[GetLength() - 1] : 0; + return m_Span.size() ? m_Span[m_Span.size() - 1] : 0; } const CharType CharAt(const size_t index) const { - ASSERT(IsValidIndex(index)); - return static_cast<CharType>(m_Ptr.Get()[index]); + return static_cast<CharType>(m_Span[index]); } Optional<size_t> Find(CharType ch) const { const auto* found = reinterpret_cast<const UnsignedType*>(FXSYS_chr( - reinterpret_cast<const CharType*>(m_Ptr.Get()), ch, m_Length)); + reinterpret_cast<const CharType*>(m_Span.data()), ch, m_Span.size())); - return found ? Optional<size_t>(found - m_Ptr.Get()) : Optional<size_t>(); + return found ? Optional<size_t>(found - m_Span.data()) : Optional<size_t>(); } bool Contains(CharType ch) const { return Find(ch).has_value(); } StringViewTemplate Mid(size_t first, size_t count) const { - if (!m_Ptr.Get()) + if (!m_Span.data()) return StringViewTemplate(); if (!IsValidIndex(first)) @@ -171,7 +166,7 @@ class StringViewTemplate { if (!IsValidIndex(first + count - 1)) return StringViewTemplate(); - return StringViewTemplate(m_Ptr.Get() + first, count); + return StringViewTemplate(m_Span.data() + first, count); } StringViewTemplate Left(size_t count) const { @@ -197,26 +192,27 @@ class StringViewTemplate { if (pos == 0) return StringViewTemplate(); - return StringViewTemplate(m_Ptr.Get(), pos); + return StringViewTemplate(m_Span.data(), pos); } bool operator<(const StringViewTemplate& that) const { - int result = FXSYS_cmp(reinterpret_cast<const CharType*>(m_Ptr.Get()), - reinterpret_cast<const CharType*>(that.m_Ptr.Get()), - std::min(m_Length, that.m_Length)); - return result < 0 || (result == 0 && m_Length < that.m_Length); + int result = + FXSYS_cmp(reinterpret_cast<const CharType*>(m_Span.data()), + reinterpret_cast<const CharType*>(that.m_Span.data()), + std::min(m_Span.size(), that.m_Span.size())); + return result < 0 || (result == 0 && m_Span.size() < that.m_Span.size()); } bool operator>(const StringViewTemplate& that) const { - int result = FXSYS_cmp(reinterpret_cast<const CharType*>(m_Ptr.Get()), - reinterpret_cast<const CharType*>(that.m_Ptr.Get()), - std::min(m_Length, that.m_Length)); - return result > 0 || (result == 0 && m_Length > that.m_Length); + int result = + FXSYS_cmp(reinterpret_cast<const CharType*>(m_Span.data()), + reinterpret_cast<const CharType*>(that.m_Span.data()), + std::min(m_Span.size(), that.m_Span.size())); + return result > 0 || (result == 0 && m_Span.size() > that.m_Span.size()); } protected: - UnownedPtr<const UnsignedType> m_Ptr; - size_t m_Length; + pdfium::span<const UnsignedType> m_Span; private: void* operator new(size_t) throw() { return nullptr; } |