// Copyright 2017 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/binary_buffer.h"

#include <algorithm>
#include <utility>

#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/span_util.h"

namespace fxcrt {

BinaryBuffer::BinaryBuffer() = default;

BinaryBuffer::BinaryBuffer(BinaryBuffer&& that) noexcept
    : m_AllocStep(that.m_AllocStep),
      m_DataSize(that.m_DataSize),
      m_buffer(std::move(that.m_buffer)) {
  // Can't just default, need to leave |that| in a valid state, which means
  // that the size members reflect the (null) moved-from buffer.
  that.m_AllocStep = 0;
  that.m_DataSize = 0;
}

BinaryBuffer::~BinaryBuffer() = default;

BinaryBuffer& BinaryBuffer::operator=(BinaryBuffer&& that) noexcept {
  // Can't just default, need to leave |that| in a valid state, which means
  // that the size members reflect the (null) moved-from buffer.
  m_AllocStep = that.m_AllocStep;
  m_DataSize = that.m_DataSize;
  m_buffer = std::move(that.m_buffer);
  that.m_AllocStep = 0;
  that.m_DataSize = 0;
  return *this;
}

void BinaryBuffer::DeleteBuf(size_t start_index, size_t count) {
  if (m_buffer.empty() || count > GetSize() || start_index > GetSize() - count)
    return;

  auto buffer_span = pdfium::make_span(m_buffer).first(GetSize());
  fxcrt::spanmove(buffer_span.subspan(start_index),
                  buffer_span.subspan(start_index + count));
  m_DataSize -= count;
}

pdfium::span<uint8_t> BinaryBuffer::GetMutableSpan() {
  return {m_buffer.data(), GetSize()};
}

pdfium::span<const uint8_t> BinaryBuffer::GetSpan() const {
  return {m_buffer.data(), GetSize()};
}

size_t BinaryBuffer::GetLength() const {
  return GetSize();
}

void BinaryBuffer::Clear() {
  m_DataSize = 0;
}

DataVector<uint8_t> BinaryBuffer::DetachBuffer() {
  m_buffer.resize(GetSize());
  m_DataSize = 0;
  return std::move(m_buffer);
}

void BinaryBuffer::EstimateSize(size_t size) {
  if (m_buffer.size() < size)
    ExpandBuf(size - GetSize());
}

void BinaryBuffer::ExpandBuf(size_t add_size) {
  FX_SAFE_SIZE_T new_size = GetSize();
  new_size += add_size;
  if (m_buffer.size() >= new_size.ValueOrDie())
    return;

  size_t alloc_step = std::max(static_cast<size_t>(128),
                               m_AllocStep ? m_AllocStep : m_buffer.size() / 4);
  new_size += alloc_step - 1;  // Quantize, don't combine these lines.
  new_size /= alloc_step;
  new_size *= alloc_step;
  m_buffer.resize(new_size.ValueOrDie());
}

void BinaryBuffer::AppendSpan(pdfium::span<const uint8_t> span) {
  if (span.empty())
    return;

  ExpandBuf(span.size());
  fxcrt::spancpy(pdfium::make_span(m_buffer).subspan(GetSize()), span);
  m_DataSize += span.size();
}

void BinaryBuffer::AppendString(const ByteString& str) {
  AppendSpan(str.raw_span());
}

void BinaryBuffer::AppendUint8(uint8_t value) {
  AppendSpan({&value, 1});
}

void BinaryBuffer::AppendUint16(uint16_t value) {
  AppendSpan({reinterpret_cast<uint8_t*>(&value), sizeof(value)});
}

void BinaryBuffer::AppendUint32(uint32_t value) {
  AppendSpan({reinterpret_cast<uint8_t*>(&value), sizeof(value)});
}

void BinaryBuffer::AppendDouble(double value) {
  AppendSpan({reinterpret_cast<uint8_t*>(&value), sizeof(value)});
}

}  // namespace fxcrt
