• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 #include "core/fxcrt/string_data_template.h"
8 
9 #include <string.h>
10 
11 #include <new>
12 
13 #include "core/fxcrt/check.h"
14 #include "core/fxcrt/check_op.h"
15 #include "core/fxcrt/fx_memory.h"
16 #include "core/fxcrt/fx_safe_types.h"
17 #include "core/fxcrt/stl_util.h"
18 
19 namespace fxcrt {
20 
21 // static
22 template <typename CharType>
Create(size_t nLen)23 RetainPtr<StringDataTemplate<CharType>> StringDataTemplate<CharType>::Create(
24     size_t nLen) {
25   DCHECK_GT(nLen, 0u);
26 
27   // Calculate space needed for the fixed portion of the struct plus the
28   // NUL char that is not included in |m_nAllocLength|.
29   int overhead = offsetof(StringDataTemplate, m_String) + sizeof(CharType);
30   FX_SAFE_SIZE_T nSize = nLen;
31   nSize *= sizeof(CharType);
32   nSize += overhead;
33 
34   // Now round to an 16-byte boundary, assuming the underlying allocator is most
35   // likely PartitionAlloc, which has 16 byte chunks. This will help with cases
36   // where we can save a re-alloc when adding a few characters to a string by
37   // using this otherwise wasted space.
38   nSize += 15;
39   nSize &= ~15;
40   size_t totalSize = nSize.ValueOrDie();
41   size_t usableLen = (totalSize - overhead) / sizeof(CharType);
42   DCHECK(usableLen >= nLen);
43 
44   void* pData = FX_StringAlloc(char, totalSize);
45   return pdfium::WrapRetain(new (pData) StringDataTemplate(nLen, usableLen));
46 }
47 
48 // static
49 template <typename CharType>
Create(pdfium::span<const CharType> str)50 RetainPtr<StringDataTemplate<CharType>> StringDataTemplate<CharType>::Create(
51     pdfium::span<const CharType> str) {
52   RetainPtr<StringDataTemplate> result = Create(str.size());
53   result->CopyContents(str);
54   return result;
55 }
56 
57 template <typename CharType>
Release()58 void StringDataTemplate<CharType>::Release() {
59   if (--m_nRefs <= 0)
60     FX_StringFree(this);
61 }
62 
63 template <typename CharType>
CopyContents(const StringDataTemplate & other)64 void StringDataTemplate<CharType>::CopyContents(
65     const StringDataTemplate& other) {
66   fxcrt::Copy(other.capacity_span().first(other.m_nDataLength + 1),
67               capacity_span());
68 }
69 
70 template <typename CharType>
CopyContents(pdfium::span<const CharType> str)71 void StringDataTemplate<CharType>::CopyContents(
72     pdfium::span<const CharType> str) {
73   fxcrt::Copy(str, capacity_span());
74   capacity_span()[str.size()] = 0;
75 }
76 
77 template <typename CharType>
CopyContentsAt(size_t offset,pdfium::span<const CharType> str)78 void StringDataTemplate<CharType>::CopyContentsAt(
79     size_t offset,
80     pdfium::span<const CharType> str) {
81   fxcrt::Copy(str, capacity_span().subspan(offset));
82   capacity_span()[offset + str.size()] = 0;
83 }
84 
85 template <typename CharType>
StringDataTemplate(size_t dataLen,size_t allocLen)86 StringDataTemplate<CharType>::StringDataTemplate(size_t dataLen,
87                                                  size_t allocLen)
88     : m_nDataLength(dataLen), m_nAllocLength(allocLen) {
89   capacity_span()[dataLen] = 0;
90 }
91 
92 // Instantiate.
93 template class StringDataTemplate<char>;
94 template class StringDataTemplate<wchar_t>;
95 
96 }  // namespace fxcrt
97