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