// 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/cfx_memorystream.h"

#include <algorithm>
#include <utility>

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

CFX_MemoryStream::CFX_MemoryStream() = default;

CFX_MemoryStream::~CFX_MemoryStream() = default;

FX_FILESIZE CFX_MemoryStream::GetSize() {
  return static_cast<FX_FILESIZE>(m_nCurSize);
}

bool CFX_MemoryStream::IsEOF() {
  return m_nCurPos >= static_cast<size_t>(GetSize());
}

FX_FILESIZE CFX_MemoryStream::GetPosition() {
  return static_cast<FX_FILESIZE>(m_nCurPos);
}

bool CFX_MemoryStream::Flush() {
  return true;
}

pdfium::span<const uint8_t> CFX_MemoryStream::GetSpan() const {
  return pdfium::make_span(m_data).first(m_nCurSize);
}

bool CFX_MemoryStream::ReadBlockAtOffset(pdfium::span<uint8_t> buffer,
                                         FX_FILESIZE offset) {
  if (buffer.empty() || offset < 0)
    return false;

  FX_SAFE_SIZE_T new_pos = buffer.size();
  new_pos += offset;
  if (!new_pos.IsValid() || new_pos.ValueOrDefault(0) == 0 ||
      new_pos.ValueOrDie() > m_nCurSize) {
    return false;
  }

  m_nCurPos = new_pos.ValueOrDie();
  // Safe to cast `offset` because it was used to calculate `new_pos` above, and
  // `new_pos` is valid.
  fxcrt::spancpy(buffer,
                 GetSpan().subspan(static_cast<size_t>(offset), buffer.size()));
  return true;
}

size_t CFX_MemoryStream::ReadBlock(pdfium::span<uint8_t> buffer) {
  if (m_nCurPos >= m_nCurSize)
    return 0;

  size_t nRead = std::min(buffer.size(), m_nCurSize - m_nCurPos);
  if (!ReadBlockAtOffset(buffer.first(nRead), static_cast<int32_t>(m_nCurPos)))
    return 0;

  return nRead;
}

bool CFX_MemoryStream::WriteBlockAtOffset(pdfium::span<const uint8_t> buffer,
                                          FX_FILESIZE offset) {
  if (offset < 0)
    return false;

  if (buffer.empty())
    return true;

  FX_SAFE_SIZE_T safe_new_pos = buffer.size();
  safe_new_pos += offset;
  if (!safe_new_pos.IsValid())
    return false;

  size_t new_pos = safe_new_pos.ValueOrDie();
  if (new_pos > m_data.size()) {
    static constexpr size_t kBlockSize = 64 * 1024;
    FX_SAFE_SIZE_T new_size = new_pos;
    new_size *= 2;
    new_size += (kBlockSize - 1);
    new_size /= kBlockSize;
    new_size *= kBlockSize;
    if (!new_size.IsValid())
      return false;

    m_data.resize(new_size.ValueOrDie());
  }
  m_nCurPos = new_pos;

  // Safe to cast `offset` because it was used to calculate `safe_new_pos`
  // above, and `safe_new_pos` is valid.
  fxcrt::spancpy(pdfium::make_span(m_data).subspan(static_cast<size_t>(offset)),
                 buffer);
  m_nCurSize = std::max(m_nCurSize, m_nCurPos);

  return true;
}
