// Copyright 2016 The Crashpad Authors. All rights reserved.
//
// 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_CLIENT_SIMPLE_ADDRESS_RANGE_BAG_H_
#define CRASHPAD_CLIENT_SIMPLE_ADDRESS_RANGE_BAG_H_

#include <stdint.h>
#include <string.h>

#include <type_traits>

#include "base/check_op.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "util/misc/from_pointer_cast.h"
#include "util/numeric/checked_range.h"

namespace crashpad {

//! \brief A bag implementation using a fixed amount of storage, so that it does
//!     not perform any dynamic allocations for its operations.
//!
//! The actual bag storage (TSimpleAddressRangeBag::Entry) is POD, so that it
//! can be transmitted over various IPC mechanisms.
template <size_t NumEntries = 64>
class TSimpleAddressRangeBag {
 public:
  //! Constant and publicly accessible version of the template parameter.
  static const size_t num_entries = NumEntries;

  //! \brief A single entry in the bag.
  struct Entry {
    //! \brief The base address of the range.
    uint64_t base;

    //! \brief The size of the range in bytes.
    uint64_t size;

    //! \brief Returns the validity of the entry.
    //!
    //! If #base and #size are both zero, the entry is considered inactive, and
    //! this method returns `false`. Otherwise, returns `true`.
    bool is_active() const {
      return base != 0 || size != 0;
    }
  };

  //! \brief An iterator to traverse all of the active entries in a
  //!     TSimpleAddressRangeBag.
  class Iterator {
   public:
    explicit Iterator(const TSimpleAddressRangeBag& bag)
        : bag_(bag),
          current_(0) {
    }

    Iterator(const Iterator&) = delete;
    Iterator& operator=(const Iterator&) = delete;

    //! \brief Returns the next entry in the bag, or `nullptr` if at the end of
    //!     the collection.
    const Entry* Next() {
      while (current_ < bag_.num_entries) {
        const Entry* entry = &bag_.entries_[current_++];
        if (entry->is_active()) {
          return entry;
        }
      }
      return nullptr;
    }

   private:
    const TSimpleAddressRangeBag& bag_;
    size_t current_;
  };

  TSimpleAddressRangeBag()
      : entries_() {
  }

  TSimpleAddressRangeBag(const TSimpleAddressRangeBag& other) {
    *this = other;
  }

  TSimpleAddressRangeBag& operator=(const TSimpleAddressRangeBag& other) {
    memcpy(entries_, other.entries_, sizeof(entries_));
    return *this;
  }

  //! \brief Returns the number of active entries. The upper limit for this is
  //!     \a NumEntries.
  size_t GetCount() const {
    size_t count = 0;
    for (size_t i = 0; i < num_entries; ++i) {
      if (entries_[i].is_active()) {
        ++count;
      }
    }
    return count;
  }

  //! \brief Inserts the given range into the bag. Duplicates and overlapping
  //! ranges are supported and allowed, but not coalesced.
  //!
  //! \param[in] range The range to be inserted. The range must have either a
  //!     non-zero base address or size.
  //!
  //! \return `true` if there was space to insert the range into the bag,
  //!     otherwise `false` with an error logged.
  bool Insert(CheckedRange<uint64_t> range) {
    DCHECK(range.base() != 0 || range.size() != 0);

    for (size_t i = 0; i < num_entries; ++i) {
      if (!entries_[i].is_active()) {
        entries_[i].base = range.base();
        entries_[i].size = range.size();
        return true;
      }
    }

    LOG(ERROR) << "no space available to insert range";
    return false;
  }

  //! \brief Inserts the given range into the bag. Duplicates and overlapping
  //! ranges are supported and allowed, but not coalesced.
  //!
  //! \param[in] base The base of the range to be inserted. May not be null.
  //! \param[in] size The size of the range to be inserted. May not be zero.
  //!
  //! \return `true` if there was space to insert the range into the bag,
  //!     otherwise `false` with an error logged.
  bool Insert(void* base, size_t size) {
    DCHECK(base != nullptr);
    DCHECK_NE(0u, size);
    return Insert(CheckedRange<uint64_t>(FromPointerCast<uint64_t>(base),
                                         base::checked_cast<uint64_t>(size)));
  }

  //! \brief Removes the given range from the bag.
  //!
  //! \param[in] range The range to be removed. The range must have either a
  //!     non-zero base address or size.
  //!
  //! \return `true` if the range was found and removed, otherwise `false` with
  //!     an error logged.
  bool Remove(CheckedRange<uint64_t> range) {
    DCHECK(range.base() != 0 || range.size() != 0);

    for (size_t i = 0; i < num_entries; ++i) {
      if (entries_[i].base == range.base() &&
          entries_[i].size == range.size()) {
        entries_[i].base = entries_[i].size = 0;
        return true;
      }
    }

    LOG(ERROR) << "did not find range to remove";
    return false;
  }

  //! \brief Removes the given range from the bag.
  //!
  //! \param[in] base The base of the range to be removed. May not be null.
  //! \param[in] size The size of the range to be removed. May not be zero.
  //!
  //! \return `true` if the range was found and removed, otherwise `false` with
  //! an error logged.
  bool Remove(void* base, size_t size) {
    DCHECK(base != nullptr);
    DCHECK_NE(0u, size);
    return Remove(CheckedRange<uint64_t>(FromPointerCast<uint64_t>(base),
                                         base::checked_cast<uint64_t>(size)));
  }


 private:
  Entry entries_[NumEntries];
};

//! \brief A TSimpleAddressRangeBag with default template parameters.
using SimpleAddressRangeBag = TSimpleAddressRangeBag<64>;

static_assert(std::is_standard_layout<SimpleAddressRangeBag>::value,
              "SimpleAddressRangeBag must be standard layout");

}  // namespace crashpad

#endif  // CRASHPAD_CLIENT_SIMPLE_ADDRESS_RANGE_BAG_H_
