// Copyright 2015 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 NET_DER_INPUT_H_
#define NET_DER_INPUT_H_

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

#include "base/compiler_specific.h"
#include "net/base/net_export.h"

namespace net {

namespace der {

class Mark;

// An opaque class that represents a fixed buffer of data of a fixed length,
// to be used as an input to other operations. An Input object does not own
// the data it references, so callers are responsible for making sure that
// the data outlives the Input object and any other associated objects.
//
// All data access for an Input should be done through the ByteReader and Mark
// classes. This class and associated classes are designed with safety in mind
// to make it difficult to read memory outside of an Input. ByteReader provides
// a simple API for reading through the Input sequentially. For more
// complicated uses, multiple instances of a ByteReader for a particular Input
// can be created, and instances of Mark can be used to coordinate between the
// ByteReaders.
//
// One such use case of multiple ByteReaders would be looking ahead in an
// input: A ByteReader is copied and then is used to read some number of
// bytes into the input, based on the content it is reading. A Mark can then be
// set using the temporary ByteReader to indicate how far it read into the
// Input. The original ByteReader can then be synchronized with how far the
// temporary ByteReader read, by using either AdvanceToMark() or ReadToMark().
class NET_EXPORT_PRIVATE Input {
 public:
  // Creates an empty Input, one from which no data can be read.
  Input();

  // Creates an Input from a constant array |data|.
  template <size_t N>
  explicit Input(const uint8_t(&data)[N])
      : data_(data), len_(N) {}

  // Creates an Input from the given |data| and |len|.
  Input(const uint8_t* data, size_t len);

  // Creates an Input from the given string |s|.
  explicit Input(const std::string& s);

  // Returns the length in bytes of an Input's data.
  size_t Length() const { return len_; }

  // Return true if the Input's data and |other|'s data are byte-wise equal.
  bool Equals(const Input& other) const;

  // Returns a pointer to the Input's data. This method is marked as "unsafe"
  // because access to the Input's data should be done through ByteReader
  // instead. This method should only be used where using a ByteReader truly
  // is not an option.
  const uint8_t* UnsafeData() const { return data_; }

 private:
  const uint8_t* data_;
  size_t len_;
};

// This class provides ways to read data from an Input in a bounds-checked way.
// The ByteReader is designed to read through the input sequentially. Once a
// byte has been read with a ByteReader, the caller can't go back and re-read
// that byte with the same reader. Of course, the caller can create multiple
// ByteReaders for the same input (or copy an existing ByteReader).
//
// For something simple like a single byte lookahead, the easiest way to do
// that is to copy the ByteReader and call ReadByte() on the copy - the original
// ByteReader will be unaffected and the peeked byte will be read through
// ReadByte(). For other read patterns, it can be useful to mark where one is
// in a ByteReader to be able to return to that spot.
//
// Some operations using Mark can also be done by creating a copy of the
// ByteReader. By using a Mark instead, you use less memory, but more
// importantly, you end up with an immutable object that matches the semantics
// of what is intended.
class NET_EXPORT_PRIVATE ByteReader {
 public:
  // Creates a ByteReader to read the data represented by an Input.
  explicit ByteReader(const Input& in);

  // Reads a single byte from the input source, putting the byte read in
  // |*byte_p|. If a byte cannot be read from the input (because there is
  // no input left), then this method returns false.
  bool ReadByte(uint8_t* out) WARN_UNUSED_RESULT;

  // Reads |len| bytes from the input source, and initializes an Input to
  // point to that data. If there aren't enough bytes left in the input source,
  // then this method returns false.
  bool ReadBytes(size_t len, Input* out) WARN_UNUSED_RESULT;

  // Returns how many bytes are left to read.
  size_t BytesLeft() const { return len_; }

  // Returns whether there is any more data to be read.
  bool HasMore();

  // Creates a new Mark at the current position of this ByteReader. If another
  // ByteReader is advanced to this mark, the next byte read by the other
  // ByteReader will be the same as the next byte read by this ByteReader.
  Mark NewMark();

  // Advances this ByteReader to the position marked by |mark|. Note that
  // a ByteReader can only advance forward - it is not possible to "rewind"
  // to a previous mark. To do this, one would need to create a new ByteReader
  // (from the same input) and AdvanceToMark() on the new ByteReader.
  //
  // If it is not possible to advance this ByteReader to the mark, this method
  // returns false and does nothing.
  bool AdvanceToMark(Mark mark) WARN_UNUSED_RESULT;

  // Reads all data from the cursor of this ByteReader up to the mark, and
  // initializes an Input to point to that data. If the Mark is not valid for
  // this ByteReader, then this method returns false and does not modify |*out|.
  bool ReadToMark(Mark mark, Input* out) WARN_UNUSED_RESULT;

 private:
  void Advance(size_t len);

  const uint8_t* data_;
  size_t len_;
};

// An immutable opaque pointer into the data represented by an Input. A Mark
// object is used to save and restore the state (position) of a ByteReader to
// allow for lookahead or backtracking. All interaction with a Mark object is
// done through the ByteReader class.
class NET_EXPORT_PRIVATE Mark {
 public:
  // Creates a null Mark. This Mark will not be usable with any ByteReader.
  // This only exists so that a class can have a Mark member which may or may
  // not be a valid Mark at any given time.
  static Mark NullMark();

  // Checks whether a given Mark is an empty Mark.
  bool IsEmpty();
  friend class ByteReader;

 private:
  explicit Mark(const uint8_t* ptr);
  Mark();
  const uint8_t* ptr_;
};

}  // namespace der

}  // namespace net

#endif  // NET_DER_INPUT_H_
