OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 |
| 7 #ifndef CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_ |
| 8 #define CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_ |
| 9 |
| 10 #include <algorithm> |
| 11 #include <type_traits> |
| 12 |
| 13 #include "core/fxcrt/include/fx_system.h" |
| 14 |
| 15 // An immutable string with caller-provided storage which must outlive the |
| 16 // string itself. These are not necessarily nul-terminated, so that substring |
| 17 // extraction (via the Mid(), Left(), and Right() methods) is copy-free. |
| 18 template <typename T> |
| 19 class CFX_StringCTemplate { |
| 20 public: |
| 21 using CharType = T; |
| 22 using UnsignedType = typename std::make_unsigned<CharType>::type; |
| 23 |
| 24 CFX_StringCTemplate() : m_Ptr(nullptr), m_Length(0) {} |
| 25 |
| 26 // Deliberately implicit to avoid calling on every string literal. |
| 27 CFX_StringCTemplate(const CharType* ptr) |
| 28 : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)), |
| 29 m_Length(ptr ? FXSYS_len(ptr) : 0) {} |
| 30 |
| 31 CFX_StringCTemplate(const CharType* ptr, FX_STRSIZE len) |
| 32 : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)), |
| 33 m_Length(len == -1 ? FXSYS_len(ptr) : len) {} |
| 34 |
| 35 template <typename U = UnsignedType> |
| 36 CFX_StringCTemplate( |
| 37 const UnsignedType* ptr, |
| 38 FX_STRSIZE size, |
| 39 typename std::enable_if<!std::is_same<U, CharType>::value>::type* = 0) |
| 40 : m_Ptr(ptr), m_Length(size) {} |
| 41 |
| 42 // Deliberately implicit to avoid calling on every string literal. |
| 43 // |ch| must be an lvalue that outlives the the CFX_StringCTemplate. |
| 44 CFX_StringCTemplate(CharType& ch) { |
| 45 m_Ptr = reinterpret_cast<const UnsignedType*>(&ch); |
| 46 m_Length = 1; |
| 47 } |
| 48 |
| 49 CFX_StringCTemplate(const CFX_StringCTemplate& src) { |
| 50 m_Ptr = src.m_Ptr; |
| 51 m_Length = src.m_Length; |
| 52 } |
| 53 |
| 54 CFX_StringCTemplate& operator=(const CharType* src) { |
| 55 m_Ptr = reinterpret_cast<const UnsignedType*>(src); |
| 56 m_Length = src ? FXSYS_len(src) : 0; |
| 57 return *this; |
| 58 } |
| 59 |
| 60 CFX_StringCTemplate& operator=(const CFX_StringCTemplate& src) { |
| 61 m_Ptr = src.m_Ptr; |
| 62 m_Length = src.m_Length; |
| 63 return *this; |
| 64 } |
| 65 |
| 66 bool operator==(const CharType* ptr) const { |
| 67 return FXSYS_len(ptr) == m_Length && |
| 68 FXSYS_cmp(ptr, reinterpret_cast<const CharType*>(m_Ptr), m_Length) == |
| 69 0; |
| 70 } |
| 71 bool operator==(const CFX_StringCTemplate& other) const { |
| 72 return other.m_Length == m_Length && |
| 73 FXSYS_cmp(reinterpret_cast<const CharType*>(other.m_Ptr), |
| 74 reinterpret_cast<const CharType*>(m_Ptr), m_Length) == 0; |
| 75 } |
| 76 bool operator!=(const CharType* ptr) const { return !(*this == ptr); } |
| 77 bool operator!=(const CFX_StringCTemplate& other) const { |
| 78 return !(*this == other); |
| 79 } |
| 80 |
| 81 uint32_t GetID(FX_STRSIZE start_pos = 0) const { |
| 82 if (m_Length == 0 || start_pos < 0 || start_pos >= m_Length) |
| 83 return 0; |
| 84 |
| 85 uint32_t strid = 0; |
| 86 FX_STRSIZE size = std::min(4, m_Length - start_pos); |
| 87 for (FX_STRSIZE i = 0; i < size; i++) |
| 88 strid = strid * 256 + m_Ptr[start_pos + i]; |
| 89 |
| 90 return strid << ((4 - size) * 8); |
| 91 } |
| 92 |
| 93 const UnsignedType* raw_str() const { return m_Ptr; } |
| 94 const CharType* c_str() const { |
| 95 return reinterpret_cast<const CharType*>(m_Ptr); |
| 96 } |
| 97 |
| 98 FX_STRSIZE GetLength() const { return m_Length; } |
| 99 bool IsEmpty() const { return m_Length == 0; } |
| 100 |
| 101 UnsignedType GetAt(FX_STRSIZE index) const { return m_Ptr[index]; } |
| 102 CharType CharAt(FX_STRSIZE index) const { |
| 103 return static_cast<CharType>(m_Ptr[index]); |
| 104 } |
| 105 |
| 106 FX_STRSIZE Find(CharType ch) const { |
| 107 const UnsignedType* found = reinterpret_cast<const UnsignedType*>( |
| 108 FXSYS_chr(reinterpret_cast<const CharType*>(m_Ptr), ch, m_Length)); |
| 109 return found ? found - m_Ptr : -1; |
| 110 } |
| 111 |
| 112 CFX_StringCTemplate Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const { |
| 113 index = std::max(0, index); |
| 114 if (index > m_Length) |
| 115 return CFX_StringCTemplate(); |
| 116 |
| 117 if (count < 0 || count > m_Length - index) |
| 118 count = m_Length - index; |
| 119 |
| 120 return CFX_StringCTemplate(m_Ptr + index, count); |
| 121 } |
| 122 |
| 123 CFX_StringCTemplate Left(FX_STRSIZE count) const { |
| 124 if (count <= 0) |
| 125 return CFX_StringCTemplate(); |
| 126 |
| 127 return CFX_StringCTemplate(m_Ptr, std::min(count, m_Length)); |
| 128 } |
| 129 |
| 130 CFX_StringCTemplate Right(FX_STRSIZE count) const { |
| 131 if (count <= 0) |
| 132 return CFX_StringCTemplate(); |
| 133 |
| 134 count = std::min(count, m_Length); |
| 135 return CFX_StringCTemplate(m_Ptr + m_Length - count, count); |
| 136 } |
| 137 |
| 138 const UnsignedType& operator[](size_t index) const { return m_Ptr[index]; } |
| 139 |
| 140 bool operator<(const CFX_StringCTemplate& that) const { |
| 141 int result = FXSYS_cmp(reinterpret_cast<const CharType*>(m_Ptr), |
| 142 reinterpret_cast<const CharType*>(that.m_Ptr), |
| 143 std::min(m_Length, that.m_Length)); |
| 144 return result < 0 || (result == 0 && m_Length < that.m_Length); |
| 145 } |
| 146 |
| 147 protected: |
| 148 const UnsignedType* m_Ptr; |
| 149 FX_STRSIZE m_Length; |
| 150 |
| 151 private: |
| 152 void* operator new(size_t) throw() { return nullptr; } |
| 153 }; |
| 154 |
| 155 template <typename T> |
| 156 inline bool operator==(const T* lhs, const CFX_StringCTemplate<T>& rhs) { |
| 157 return rhs == lhs; |
| 158 } |
| 159 |
| 160 template <typename T> |
| 161 inline bool operator!=(const T* lhs, const CFX_StringCTemplate<T>& rhs) { |
| 162 return rhs != lhs; |
| 163 } |
| 164 |
| 165 extern template class CFX_StringCTemplate<FX_CHAR>; |
| 166 extern template class CFX_StringCTemplate<FX_WCHAR>; |
| 167 |
| 168 #endif // CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_ |
OLD | NEW |