/**
* Copyright (c) 2018 Cornell University.
*
* Author: Ted Yin <tederminant@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _SALTICIDAE_CONN_H
#define _SALTICIDAE_CONN_H
#include <cassert>
#include <cstdint>
#include <event2/event.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <unordered_map>
#include <list>
#include <algorithm>
#include <exception>
#include "salticidae/type.h"
#include "salticidae/ref.h"
#include "salticidae/event.h"
#include "salticidae/util.h"
#include "salticidae/netaddr.h"
#include "salticidae/msg.h"
namespace salticidae {
class RingBuffer {
struct buffer_entry_t {
bytearray_t data;
bytearray_t::iterator offset;
buffer_entry_t(bytearray_t &&_data): data(std::move(_data)) {
offset = data.begin();
}
buffer_entry_t(buffer_entry_t &&other) {
size_t _offset = other.offset - other.data.begin();
data = std::move(other.data);
offset = data.begin() + _offset;
}
buffer_entry_t(const buffer_entry_t &other): data(other.data) {
offset = data.begin() + (other.offset - other.data.begin());
}
size_t length() const { return data.end() - offset; }
};
std::list<buffer_entry_t> ring;
size_t _size;
public:
RingBuffer(): _size(0) {}
~RingBuffer() { clear(); }
void swap(RingBuffer &other) {
std::swap(ring, other.ring);
std::swap(_size, other._size);
}
RingBuffer(const RingBuffer &other):
ring(other.ring), _size(other._size) {}
RingBuffer(RingBuffer &&other):
ring(std::move(other.ring)), _size(other._size) {
other._size = 0;
}
RingBuffer &operator=(RingBuffer &&other) {
if (this != &other)
{
RingBuffer tmp(std::move(other));
tmp.swap(*this);
}
return *this;
}
RingBuffer &operator=(const RingBuffer &other) {
if (this != &other)
{
RingBuffer tmp(other);
tmp.swap(*this);
}
return *this;
}
void push(bytearray_t &&data) {
_size += data.size();
ring.push_back(buffer_entry_t(std::move(data)));
}
bytearray_t pop(size_t len) {
bytearray_t res;
auto i = ring.begin();
while (len && i != ring.end())
{
size_t copy_len = std::min(i->length(), len);
res.insert(res.end(),