• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The PDFium Authors
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_STRING_DATA_TEMPLATE_H_
8 #define CORE_FXCRT_STRING_DATA_TEMPLATE_H_
9 
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include <string>
14 
15 #include "core/fxcrt/retain_ptr.h"
16 #include "core/fxcrt/span.h"
17 
18 namespace fxcrt {
19 
20 template <typename CharType>
21 class StringDataTemplate {
22  public:
23   static RetainPtr<StringDataTemplate> Create(size_t nLen);
24   static RetainPtr<StringDataTemplate> Create(pdfium::span<const CharType> str);
25 
Retain()26   void Retain() { ++m_nRefs; }
27   void Release();
28 
CanOperateInPlace(size_t nTotalLen)29   bool CanOperateInPlace(size_t nTotalLen) const {
30     return m_nRefs <= 1 && nTotalLen <= m_nAllocLength;
31   }
32 
33   void CopyContents(const StringDataTemplate& other);
34   void CopyContents(pdfium::span<const CharType> str);
35   void CopyContentsAt(size_t offset, pdfium::span<const CharType> str);
36 
span()37   pdfium::span<CharType> span() {
38     // SAFETY: m_nDataLength is within m_String.
39     return UNSAFE_BUFFERS(pdfium::make_span(m_String, m_nDataLength));
40   }
span()41   pdfium::span<const CharType> span() const {
42     // SAFETY: m_nDataLength is within m_String.
43     return UNSAFE_BUFFERS(pdfium::make_span(m_String, m_nDataLength));
44   }
45 
46   // Only a const-form is provided to preclude modifying the terminator.
span_with_terminator()47   pdfium::span<const CharType> span_with_terminator() const {
48     // SAFETY: m_nDataLength is within m_String and there is always a
49     // terminator character following it.
50     return UNSAFE_BUFFERS(pdfium::make_span(m_String, m_nDataLength + 1));
51   }
52 
alloc_span()53   pdfium::span<CharType> alloc_span() {
54     // SAFETY: m_nAllocLength is within m_String.
55     return UNSAFE_BUFFERS(pdfium::make_span(m_String, m_nAllocLength));
56   }
alloc_span()57   pdfium::span<const CharType> alloc_span() const {
58     // SAFETY: m_nAllocLength is within m_String.
59     return UNSAFE_BUFFERS(pdfium::make_span(m_String, m_nAllocLength));
60   }
61 
62   // Includes the terminating NUL not included in lengths.
capacity_span()63   pdfium::span<CharType> capacity_span() {
64     // SAFETY: m_nAllocLength + 1 is within m_String.
65     return UNSAFE_BUFFERS(pdfium::make_span(m_String, m_nAllocLength + 1));
66   }
capacity_span()67   pdfium::span<const CharType> capacity_span() const {
68     // SAFETY: m_nAllocLength + 1 is within m_String.
69     return UNSAFE_BUFFERS(pdfium::make_span(m_String, m_nAllocLength + 1));
70   }
71 
72   // Return length as determined by the location of the first embedded NUL.
GetStringLength()73   size_t GetStringLength() const {
74     return std::char_traits<CharType>::length(m_String);
75   }
76 
77   // Unlike std::string::front(), this is always safe and returns a
78   // NUL char when the string is empty.
Front()79   CharType Front() const { return !span().empty() ? span().front() : 0; }
80 
81   // Unlike std::string::back(), this is always safe and returns a
82   // NUL char when the string is empty.
Back()83   CharType Back() const { return !span().empty() ? span().back() : 0; }
84 
85   // To ensure ref counts do not overflow, consider the worst possible case:
86   // the entire address space contains nothing but pointers to this object.
87   // Since the count increments with each new pointer, the largest value is
88   // the number of pointers that can fit into the address space. The size of
89   // the address space itself is a good upper bound on it.
90   intptr_t m_nRefs = 0;
91 
92   // These lengths are in terms of number of characters, not bytes, and do not
93   // include the terminating NUL character, but the underlying buffer is sized
94   // to be capable of holding it.
95   size_t m_nDataLength;
96   const size_t m_nAllocLength;
97 
98   // Not really 1, variable size.
99   CharType m_String[1];
100 
101  private:
102   StringDataTemplate(size_t dataLen, size_t allocLen);
103   ~StringDataTemplate() = delete;
104 };
105 
106 extern template class StringDataTemplate<char>;
107 extern template class StringDataTemplate<wchar_t>;
108 
109 }  // namespace fxcrt
110 
111 using fxcrt::StringDataTemplate;
112 
113 #endif  // CORE_FXCRT_STRING_DATA_TEMPLATE_H_
114