// Copyright 2014 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_
#define CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_

#include <stdint.h>
#include <sys/types.h>

#include <memory>

#include "util/numeric/checked_range.h"

namespace crashpad {

//! \brief An abstract interface to a snapshot representing a region of memory
//!     present in a snapshot process.
class MemorySnapshot {
 public:
  //! \brief An interface that MemorySnapshot clients must implement in order to
  //!     receive memory snapshot data.
  //!
  //! This callback-based model frees MemorySnapshot implementations from having
  //! to deal with memory region ownership problems. When a memory snapshot’s
  //! data is read, it will be passed to a delegate method.
  class Delegate {
   public:
    virtual ~Delegate() {}

    //! \brief Called by MemorySnapshot::Read() to provide data requested by a
    //!     call to that method.
    //!
    //! \param[in] data A pointer to the data that was read. The callee does not
    //!     take ownership of this data. This data is only valid for the
    //!     duration of the call to this method. This parameter may be `nullptr`
    //!     if \a size is `0`.
    //! \param[in] size The size of the data that was read.
    //!
    //! \return `true` on success, `false` on failure. MemoryDelegate::Read()
    //!     will use this as its own return value.
    virtual bool MemorySnapshotDelegateRead(void* data, size_t size) = 0;
  };

  virtual ~MemorySnapshot() {}

  //! \brief The base address of the memory snapshot in the snapshot process’
  //!     address space.
  virtual uint64_t Address() const = 0;

  //! \brief The size of the memory snapshot.
  virtual size_t Size() const = 0;

  //! \brief Calls Delegate::MemorySnapshotDelegateRead(), providing it with
  //!     the memory snapshot’s data.
  //!
  //! Implementations do not necessarily read the memory snapshot data prior to
  //! this method being called. Memory snapshot data may be loaded lazily and
  //! may be discarded after being passed to the delegate. This provides clean
  //! memory management without burdening a snapshot implementation with the
  //! requirement that it track all memory region data simultaneously.
  //!
  //! \return `false` on failure, otherwise, the return value of
  //!     Delegate::MemorySnapshotDelegateRead(), which should be `true` on
  //!     success and `false` on failure.
  virtual bool Read(Delegate* delegate) const = 0;

  //! \brief Creates a new MemorySnapshot based on merging this one with \a
  //!     other.
  //!
  //! The ranges described by the two snapshots must either overlap or abut, and
  //! must be of the same concrete type.
  //!
  //! \return A newly allocated MemorySnapshot representing the merged range, or
  //!     `nullptr` with an error logged.
  virtual const MemorySnapshot* MergeWithOtherSnapshot(
      const MemorySnapshot* other) const = 0;
};

//! \brief Given two memory snapshots, checks if they're overlapping or
//!     abutting, and if so, returns the result of merging the two ranges.
//!
//! This function is useful to implement
//! MemorySnapshot::MergeWithOtherSnapshot().
//!
//! \param[in] a The first range. Must have Size() > 0.
//! \param[in] b The second range. Must have Size() > 0.
//! \param[out] merged The resulting merged range. May be `nullptr` if only a
//!     characterization of the ranges is desired.
//!
//! \return `true` if the input ranges overlap or abut, with \a merged filled
//!     out, otherwise, `false` with an error logged if \a log is `true`.
bool LoggingDetermineMergedRange(const MemorySnapshot* a,
                                 const MemorySnapshot* b,
                                 CheckedRange<uint64_t, size_t>* merged);

//! \brief The same as LoggingDetermineMergedRange but with no errors logged.
//!
//! \sa LoggingDetermineMergedRange
bool DetermineMergedRange(const MemorySnapshot* a,
                          const MemorySnapshot* b,
                          CheckedRange<uint64_t, size_t>* merged);

}  // namespace crashpad

#endif  // CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_
