// 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/stl_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::Copy(GetSpan().subspan(static_cast<size_t>(offset), buffer.size()),
              buffer);
  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::Copy(buffer,
              pdfium::make_span(m_data).subspan(static_cast<size_t>(offset)));
  m_nCurSize = std::max(m_nCurSize, m_nCurPos);

  return true;
}
