// Copyright 2013 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_QUIC_IOVECTOR_H_
#define NET_QUIC_IOVECTOR_H_

#include <stddef.h>
#include <algorithm>
#include <vector>

#include "base/basictypes.h"
#include "base/logging.h"
#include "net/base/iovec.h"
#include "net/base/net_export.h"

namespace net {

// Calculate the total number of bytes in an array of iovec structures.
inline size_t TotalIovecLength(const struct iovec* iov, size_t iovcnt) {
  size_t length = 0;
  if (iov != NULL) {
    for (size_t i = 0; i < iovcnt; ++i) {
      length += iov[i].iov_len;
    }
  }
  return length;
}

// IOVector is a helper class that makes it easier to work with POSIX vector I/O
// struct. It is a thin wrapper by design and thus has no virtual functions and
// all inlined methods. This class makes no assumptions about the ordering of
// the pointer values of the blocks appended, it simply counts bytes when asked
// to consume bytes.
//
// IOVector is a bookkeeping object that collects a description of buffers to
// be read or written together and in order. It does not take ownership of the
// blocks appended.
//
// Because it is used for scatter-gather operations, the order in which the
// buffer blocks are added to the IOVector is important to the client. The
// intended usage pattern is:
//
//   iovector.Append(p0, len0);
//   ...
//   iovector.Append(pn, lenn);
//   int bytes_written = writev(fd, iovector.iovec(), iovector.Size());
//   if (bytes_written > 0)
//     iovector.Consume(bytes_written);
//
// The sequence is the same for readv, except that Consume() in this case is
// used to change the IOVector to only keep track of description of blocks of
// memory not yet written to.
//
// IOVector does not have any method to change the iovec entries that it
// accumulates. This is due to the block merging nature of Append(): we'd like
// to avoid accidentally change an entry that is assembled by two or more
// Append()'s by simply an index access.
//
class NET_EXPORT_PRIVATE IOVector {
 public:
  // Provide a default constructor so it'll never be inhibited by adding other
  // constructors.
  IOVector();
  ~IOVector();

  // Provides a way to convert system call-like iovec representation to
  // IOVector.
  void AppendIovec(const struct iovec* iov, size_t iovcnt) {
    for (size_t i = 0; i < iovcnt; ++i)
      Append(static_cast<char*>(iov[i].iov_base), iov[i].iov_len);
  }

  // Appends at most max_bytes from iovec to the IOVector.
  size_t AppendIovecAtMostBytes(const struct iovec* iov,
                                size_t iovcnt,
                                size_t max_bytes) {
    size_t bytes_appended = 0;
    for (size_t i = 0; i < iovcnt && max_bytes > 0; ++i) {
      const size_t length = std::min(max_bytes, iov[i].iov_len);
      Append(static_cast<char*>(iov[i].iov_base), length);
      max_bytes -= length;
      bytes_appended += length;
    }
    return bytes_appended;
  }

  // Append another block to the IOVector. Since IOVector can be used for read
  // and write, it always takes char*. Clients that writes will need to cast
  // away the constant of the pointer before appending a block.
  void Append(char* buffer, size_t length) {
    if (buffer != NULL && length > 0) {
      if (iovec_.size() > 0) {
        struct iovec& last = iovec_.back();
        // If the new block is contiguous with the last block, just extend.
        if (static_cast<char*>(last.iov_base) + last.iov_len == buffer) {
          last.iov_len += length;
          return;
        }
      }
      struct iovec tmp = {buffer, length};
      iovec_.push_back(tmp);
    }
  }

  // Same as Append, but doesn't do the tail merge optimization.
  // Intended for testing.
  void AppendNoCoalesce(char* buffer, size_t length) {
    if (buffer != NULL && length > 0) {
      struct iovec tmp = {buffer, length};
      iovec_.push_back(tmp);
    }
  }

  // Remove a number of bytes from the beginning of the IOVector. Since vector
  // I/O operations always occur at the beginning of the block list, a method
  // to remove bytes at the end is not provided.
  // It returns the number of bytes actually consumed (it'll only be smaller
  // than the requested number if the IOVector contains less data).
  size_t Consume(size_t length) {
    if (length == 0) return 0;

    size_t bytes_to_consume = length;
    std::vector<struct iovec>::iterator iter = iovec_.begin();
    std::vector<struct iovec>::iterator end = iovec_.end();
    for (; iter < end && bytes_to_consume >= iter->iov_len; ++iter) {
      bytes_to_consume -= iter->iov_len;
    }
    iovec_.erase(iovec_.begin(), iter);
    if (iovec_.size() > 0 && bytes_to_consume != 0) {
      iovec_[0].iov_base =
          static_cast<char*>(iovec_[0].iov_base) + bytes_to_consume;
      iovec_[0].iov_len -= bytes_to_consume;
      return length;
    }
    if (iovec_.size() == 0 && bytes_to_consume > 0) {
      LOG(DFATAL) << "Attempting to consume " << bytes_to_consume
                  << " non-existent bytes.";
    }
    // At this point bytes_to_consume is the number of wanted bytes left over
    // after walking through all the iovec entries.
    return length - bytes_to_consume;
  }

  // TODO(joechan): If capacity is large, swap out for a blank one.
  // Clears the IOVector object to contain no blocks.
  void Clear() { iovec_.clear(); }

  // Swap the guts of two IOVector.
  void Swap(IOVector* other) { iovec_.swap(other->iovec_); }

  // Returns the number of valid blocks in the IOVector (not the number of
  // bytes).
  size_t Size() const { return iovec_.size(); }

  // Returns the total storage used by the IOVector in number of blocks (not
  // the number of bytes).
  size_t Capacity() const { return iovec_.capacity(); }

  // Returns true if there are no blocks in the IOVector.
  bool Empty() const { return iovec_.empty(); }

  // Returns the pointer to the beginning of the iovec to be used for vector
  // I/O operations. If the IOVector has no blocks appened, this function
  // returns NULL.
  struct iovec* iovec() { return !Empty() ? &iovec_[0] : NULL; }

  // Const version.
  const struct iovec* iovec() const { return !Empty() ? &iovec_[0] : NULL; }

  // Returns a pointer to one past the last byte of the last block. If the
  // IOVector is empty, NULL is returned.
  const char* LastBlockEnd() const {
    return iovec_.size() > 0 ?
        static_cast<char *>(iovec_.back().iov_base) + iovec_.back().iov_len :
        NULL;
  }

  // Returns the total number of bytes in the IOVector.
  size_t TotalBufferSize() const { return TotalIovecLength(iovec(), Size()); }

  void Resize(size_t count) {
    iovec_.resize(count);
  }

 private:
  std::vector<struct iovec> iovec_;

  // IOVector has value-semantics; copy and assignment are allowed.
  // This class does not explicitly define copy/move constructors or the
  // assignment operator to preserve compiler-generated copy/move constructors
  // and assignment operators. Note that since IOVector does not own the
  // actual buffers that the struct iovecs point to, copies and assignments
  // result in a shallow copy of the buffers; resulting IOVectors will point
  // to the same copy of the underlying data.
};

}  // namespace net

#endif  // NET_QUIC_IOVECTOR_H_
