blob: 30ca0a6a398a16e17c317fe50ace34b53493bb51 [file] [log] [blame]
// Copyright 2020 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "core/fxcrt/string_data_template.h"
#include <string.h>
#include <new>
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/span_util.h"
namespace fxcrt {
// static
template <typename CharType>
RetainPtr<StringDataTemplate<CharType>> StringDataTemplate<CharType>::Create(
size_t nLen) {
DCHECK_GT(nLen, 0u);
// Calculate space needed for the fixed portion of the struct plus the
// NUL char that is not included in |m_nAllocLength|.
int overhead = offsetof(StringDataTemplate, m_String) + sizeof(CharType);
FX_SAFE_SIZE_T nSize = nLen;
nSize *= sizeof(CharType);
nSize += overhead;
// Now round to an 16-byte boundary, assuming the underlying allocator is most
// likely PartitionAlloc, which has 16 byte chunks. This will help with cases
// where we can save a re-alloc when adding a few characters to a string by
// using this otherwise wasted space.
nSize += 15;
nSize &= ~15;
size_t totalSize = nSize.ValueOrDie();
size_t usableLen = (totalSize - overhead) / sizeof(CharType);
DCHECK(usableLen >= nLen);
void* pData = FX_StringAlloc(char, totalSize);
return pdfium::WrapRetain(new (pData) StringDataTemplate(nLen, usableLen));
}
// static
template <typename CharType>
RetainPtr<StringDataTemplate<CharType>> StringDataTemplate<CharType>::Create(
pdfium::span<const CharType> str) {
RetainPtr<StringDataTemplate> result = Create(str.size());
result->CopyContents(str);
return result;
}
template <typename CharType>
void StringDataTemplate<CharType>::Release() {
if (--m_nRefs <= 0)
FX_StringFree(this);
}
template <typename CharType>
void StringDataTemplate<CharType>::CopyContents(
const StringDataTemplate& other) {
fxcrt::spancpy(capacity_span(),
other.capacity_span().first(other.m_nDataLength + 1));
}
template <typename CharType>
void StringDataTemplate<CharType>::CopyContents(
pdfium::span<const CharType> str) {
fxcrt::spancpy(capacity_span(), str);
capacity_span()[str.size()] = 0;
}
template <typename CharType>
void StringDataTemplate<CharType>::CopyContentsAt(
size_t offset,
pdfium::span<const CharType> str) {
fxcrt::spancpy(capacity_span().subspan(offset), str);
capacity_span()[offset + str.size()] = 0;
}
template <typename CharType>
StringDataTemplate<CharType>::StringDataTemplate(size_t dataLen,
size_t allocLen)
: m_nDataLength(dataLen), m_nAllocLength(allocLen) {
capacity_span()[dataLen] = 0;
}
// Instantiate.
template class StringDataTemplate<char>;
template class StringDataTemplate<wchar_t>;
} // namespace fxcrt