// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__
#define SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__

#include <stdint.h>

#include <iterator>

#include "base/macros.h"
#include "sandbox/sandbox_export.h"

namespace sandbox {

// Iterates over the entire system call range from 0..0xFFFFFFFFu. This
// iterator is aware of how system calls look like and will skip quickly
// over ranges that can't contain system calls. It iterates more slowly
// whenever it reaches a range that is potentially problematic, returning
// the last invalid value before a valid range of system calls, and the
// first invalid value after a valid range of syscalls. It iterates over
// individual values whenever it is in the normal range for system calls
// (typically MIN_SYSCALL..MAX_SYSCALL).
//
// Example usage:
//   for (uint32_t sysnum : SyscallSet::All()) {
//     // Do something with sysnum.
//   }
class SANDBOX_EXPORT SyscallSet {
 public:
  class Iterator;

  SyscallSet(const SyscallSet& ss) : set_(ss.set_) {}
  ~SyscallSet() {}

  Iterator begin() const;
  Iterator end() const;

  // All returns a SyscallSet that contains both valid and invalid
  // system call numbers.
  static SyscallSet All() { return SyscallSet(Set::ALL); }

  // ValidOnly returns a SyscallSet that contains only valid system
  // call numbers.
  static SyscallSet ValidOnly() { return SyscallSet(Set::VALID_ONLY); }

  // InvalidOnly returns a SyscallSet that contains only invalid
  // system call numbers, but still omits numbers in the middle of a
  // range of invalid system call numbers.
  static SyscallSet InvalidOnly() { return SyscallSet(Set::INVALID_ONLY); }

  // IsValid returns whether |num| specifies a valid system call
  // number.
  static bool IsValid(uint32_t num);

 private:
  enum class Set { ALL, VALID_ONLY, INVALID_ONLY };

  explicit SyscallSet(Set set) : set_(set) {}

  Set set_;

  friend bool operator==(const SyscallSet&, const SyscallSet&);
  DISALLOW_ASSIGN(SyscallSet);
};

SANDBOX_EXPORT bool operator==(const SyscallSet& lhs, const SyscallSet& rhs);

// Iterator provides C++ input iterator semantics for traversing a
// SyscallSet.
class SyscallSet::Iterator
    : public std::iterator<std::input_iterator_tag, uint32_t> {
 public:
  Iterator(const Iterator& it)
      : set_(it.set_), done_(it.done_), num_(it.num_) {}
  ~Iterator() {}

  uint32_t operator*() const;
  Iterator& operator++();

 private:
  Iterator(Set set, bool done);

  uint32_t NextSyscall() const;

  Set set_;
  bool done_;
  uint32_t num_;

  friend SyscallSet;
  friend bool operator==(const Iterator&, const Iterator&);
  DISALLOW_ASSIGN(Iterator);
};

SANDBOX_EXPORT bool operator==(const SyscallSet::Iterator& lhs,
                               const SyscallSet::Iterator& rhs);
SANDBOX_EXPORT bool operator!=(const SyscallSet::Iterator& lhs,
                               const SyscallSet::Iterator& rhs);

}  // namespace sandbox

#endif  // SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__
