// Copyright 2020 PDFium Authors. All rights reserved.
// 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 "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_safe_types.h"
#include "third_party/base/allocator/partition_allocator/partition_alloc.h"
#include "third_party/base/check.h"

namespace fxcrt {

// static
template <typename CharType>
StringDataTemplate<CharType>* StringDataTemplate<CharType>::Create(
    size_t nLen) {
  DCHECK(nLen > 0);

  // 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 = GetStringPartitionAllocator().root()->Alloc(
      totalSize, "StringDataTemplate");
  return new (pData) StringDataTemplate(nLen, usableLen);
}

// static
template <typename CharType>
StringDataTemplate<CharType>* StringDataTemplate<CharType>::Create(
    const CharType* pStr,
    size_t nLen) {
  StringDataTemplate* result = Create(nLen);
  result->CopyContents(pStr, nLen);
  return result;
}

template <typename CharType>
void StringDataTemplate<CharType>::Release() {
  if (--m_nRefs <= 0)
    GetStringPartitionAllocator().root()->Free(this);
}

template <typename CharType>
void StringDataTemplate<CharType>::CopyContents(
    const StringDataTemplate& other) {
  DCHECK(other.m_nDataLength <= m_nAllocLength);
  memcpy(m_String, other.m_String,
         (other.m_nDataLength + 1) * sizeof(CharType));
}

template <typename CharType>
void StringDataTemplate<CharType>::CopyContents(const CharType* pStr,
                                                size_t nLen) {
  DCHECK(nLen >= 0);
  DCHECK(nLen <= m_nAllocLength);

  memcpy(m_String, pStr, nLen * sizeof(CharType));
  m_String[nLen] = 0;
}

template <typename CharType>
void StringDataTemplate<CharType>::CopyContentsAt(size_t offset,
                                                  const CharType* pStr,
                                                  size_t nLen) {
  DCHECK(offset >= 0);
  DCHECK(nLen >= 0);
  DCHECK(offset + nLen <= m_nAllocLength);

  memcpy(m_String + offset, pStr, nLen * sizeof(CharType));
  m_String[offset + nLen] = 0;
}

template <typename CharType>
StringDataTemplate<CharType>::StringDataTemplate(size_t dataLen,
                                                 size_t allocLen)
    : m_nDataLength(dataLen), m_nAllocLength(allocLen) {
  DCHECK(dataLen >= 0);
  DCHECK(dataLen <= allocLen);
  m_String[dataLen] = 0;
}

template class StringDataTemplate<char>;
template class StringDataTemplate<wchar_t>;

}  // namespace fxcrt
