~ne02ptzero/pistache

f2f5a50fbfb5b8ef6cf1d3d2a9d442a8270e375d — Igor [hyperxor] 4 years ago 7b12580
Raw buffer refactoring (#806)

* RawBuffer refactoring + tests

* apply clang-format
4 files changed, 47 insertions(+), 45 deletions(-)

M include/pistache/stream.h
M include/pistache/transport.h
M src/common/stream.cc
M tests/stream_test.cc
M include/pistache/stream.h => include/pistache/stream.h +13 -8
@@ 103,20 103,25 @@ private:
  size_t maxSize = Const::MaxBuffer;
};

struct RawBuffer {
  RawBuffer();
  RawBuffer(std::string data, size_t length, bool isDetached = false);
  RawBuffer(const char *data, size_t length, bool isDetached = false);
struct RawBuffer final {
  RawBuffer() = default;
  RawBuffer(std::string data, size_t length);
  RawBuffer(const char *data, size_t length);

  RawBuffer detach(size_t fromIndex);
  RawBuffer(const RawBuffer &) = default;
  RawBuffer &operator=(const RawBuffer &) = default;
  RawBuffer(RawBuffer &&) = default;
  RawBuffer &operator=(RawBuffer &&) = default;

  ~RawBuffer() = default;

  RawBuffer copy(size_t fromIndex = 0u) const;
  const std::string &data() const;
  size_t size() const;
  bool isDetached() const;

private:
  std::string data_;
  size_t length_;
  bool isDetached_;
  size_t length_ = 0;
};

struct FileBuffer {

M include/pistache/transport.h => include/pistache/transport.h +8 -13
@@ 43,10 43,8 @@ public:
    // context means chunked responses could be sent out of order.
    return Async::Promise<ssize_t>(
        [=](Async::Deferred<ssize_t> deferred) mutable {
          BufferHolder holder(buffer);
          auto detached = holder.detach();
          WriteEntry write(std::move(deferred), detached, flags);
          write.peerFd = fd;
          BufferHolder holder{buffer};
          WriteEntry write(std::move(deferred), std::move(holder), fd, flags);
          writesQueue.push(std::move(write));
        });
  }


@@ 104,10 102,7 @@ private:
      if (!isRaw())
        return BufferHolder(_fd, size_, offset);

      if (_raw.isDetached())
        return BufferHolder(_raw, offset);

      auto detached = _raw.detach(offset);
      auto detached = _raw.copy(offset);
      return BufferHolder(detached);
    }



@@ 125,14 120,14 @@ private:

  struct WriteEntry {
    WriteEntry(Async::Deferred<ssize_t> deferred_, BufferHolder buffer_,
               int flags_ = 0)
               Fd peerFd_, int flags_ = 0)
        : deferred(std::move(deferred_)), buffer(std::move(buffer_)),
          flags(flags_), peerFd(-1) {}
          flags(flags_), peerFd(peerFd_) {}

    Async::Deferred<ssize_t> deferred;
    BufferHolder buffer;
    int flags;
    Fd peerFd;
    int flags = 0;
    Fd peerFd = -1;
  };

  struct TimerEntry {


@@ 194,7 189,7 @@ private:

  // This will attempt to drain the write queue for the fd
  void asyncWriteImpl(Fd fd);
  ssize_t sendRawBuffer(Fd fd, const char* buffer, size_t len, int flags);
  ssize_t sendRawBuffer(Fd fd, const char *buffer, size_t len, int flags);
  ssize_t sendFile(Fd fd, Fd file, off_t offset, size_t len);

  void handlePeerDisconnection(const std::shared_ptr<Peer> &peer);

M src/common/stream.cc => src/common/stream.cc +17 -16
@@ 17,18 17,16 @@

namespace Pistache {

RawBuffer::RawBuffer() : data_(), length_(0), isDetached_(false) {}
RawBuffer::RawBuffer(std::string data, size_t length)
    : data_(std::move(data)), length_(length) {}

RawBuffer::RawBuffer(std::string data, size_t length, bool isDetached)
    : data_(std::move(data)), length_(length), isDetached_(isDetached) {}

RawBuffer::RawBuffer(const char *data, size_t length, bool isDetached)
    : data_(), length_(length), isDetached_(isDetached) {
RawBuffer::RawBuffer(const char *data, size_t length)
    : data_(), length_(length) {
  // input may come not from a ZTS - copy only length_ characters.
  data_.assign(data, length_);
}

RawBuffer RawBuffer::detach(size_t fromIndex) {
RawBuffer RawBuffer::copy(size_t fromIndex) const {
  if (data_.empty())
    return RawBuffer();



@@ 39,15 37,13 @@ RawBuffer RawBuffer::detach(size_t fromIndex) {
  auto newDatalength = length_ - fromIndex;
  std::string newData = data_.substr(fromIndex, newDatalength);

  return RawBuffer(std::move(newData), newDatalength, true);
  return RawBuffer(std::move(newData), newDatalength);
}

const std::string &RawBuffer::data() const { return data_; }

size_t RawBuffer::size() const { return length_; }

bool RawBuffer::isDetached() const { return isDetached_; }

FileBuffer::FileBuffer(const std::string &fileName)
    : fileName_(fileName), fd_(-1), size_(0) {
  if (fileName.empty()) {


@@ 218,10 214,11 @@ bool match_literal(char c, StreamCursor &cursor, CaseSensitivity cs) {
  if (cursor.eof())
    return false;

  char lhs = (cs == CaseSensitivity::Sensitive ? c : static_cast<char>(std::tolower(c)));
  char rhs =
      (cs == CaseSensitivity::Sensitive ? cursor.current()
                                        : static_cast<char>(std::tolower(cursor.current())));
  char lhs = (cs == CaseSensitivity::Sensitive ? c : static_cast<char>(
                                                         std::tolower(c)));
  char rhs = (cs == CaseSensitivity::Sensitive
                  ? cursor.current()
                  : static_cast<char>(std::tolower(cursor.current())));

  if (lhs == rhs) {
    cursor.advance(1);


@@ 242,8 239,12 @@ bool match_until(std::initializer_list<char> chars, StreamCursor &cursor,

  auto find = [&](char val) {
    for (auto c : chars) {
      char lhs = cs == CaseSensitivity::Sensitive ? c : static_cast<char>(std::tolower(c));
      char rhs = cs == CaseSensitivity::Insensitive ? val : static_cast<char>(std::tolower(val));
      char lhs = cs == CaseSensitivity::Sensitive
                     ? c
                     : static_cast<char>(std::tolower(c));
      char rhs = cs == CaseSensitivity::Insensitive
                     ? val
                     : static_cast<char>(std::tolower(val));

      if (lhs == rhs)
        return true;

M tests/stream_test.cc => tests/stream_test.cc +9 -8
@@ 15,21 15,23 @@ using namespace Pistache;
TEST(stream, test_buffer) {
  const char str[] = "test_string";
  const size_t len = strlen(str);
  RawBuffer buffer1(str, len, false);
  RawBuffer buffer1(str, len);

  RawBuffer buffer2 = buffer1.detach(0);
  ASSERT_THROW(buffer1.copy(2 * len), std::range_error);

  RawBuffer buffer2 = buffer1.copy();
  ASSERT_EQ(buffer2.size(), len);
  ASSERT_EQ(buffer2.isDetached(), true);
  ASSERT_EQ(buffer2.data(), "test_string");

  RawBuffer buffer3;
  ASSERT_EQ(buffer3.size(), 0u);
  ASSERT_EQ(buffer3.isDetached(), false);

  RawBuffer buffer4 = buffer3.detach(0);
  RawBuffer buffer4 = buffer3.copy();
  ASSERT_EQ(buffer4.size(), 0u);
  ASSERT_EQ(buffer4.isDetached(), false);

  ASSERT_THROW(buffer1.detach(2 * len), std::range_error);
  RawBuffer buffer5 = buffer1.copy(5u);
  ASSERT_EQ(buffer5.size(), 6u);
  ASSERT_EQ(buffer5.data(), "string");
}

TEST(stream, test_file_buffer) {


@@ 68,7 70,6 @@ TEST(stream, test_dyn_buffer) {
  auto rawbuf = buf.buffer();

  ASSERT_EQ(rawbuf.size(), 128u);
  ASSERT_EQ(rawbuf.isDetached(), false);
  ASSERT_EQ(rawbuf.data().size(), 128u);
  ASSERT_EQ(strlen(rawbuf.data().c_str()), 128u);
}