Commit 86db2e75 authored by Dominik Charousset's avatar Dominik Charousset

{detail => util}::buffer; buffer is no longer a template

parent ca54336f
......@@ -83,6 +83,7 @@ set(LIBCPPA_SRC
src/behavior_stack.cpp
src/binary_deserializer.cpp
src/binary_serializer.cpp
src/buffer.cpp
src/channel.cpp
src/thread_mapped_actor.cpp
src/demangle.cpp
......@@ -99,6 +100,7 @@ set(LIBCPPA_SRC
src/ipv4_io_stream.cpp
src/local_actor.cpp
src/mailman.cpp
src/middleman.cpp
src/network_manager.cpp
src/object.cpp
src/object_array.cpp
......
......@@ -43,7 +43,6 @@ cppa/detail/actor_registry.hpp
cppa/detail/addressed_message.hpp
cppa/detail/atom_val.hpp
cppa/detail/boxed.hpp
cppa/detail/buffer.hpp
cppa/detail/channel.hpp
cppa/detail/container_tuple_view.hpp
cppa/thread_mapped_actor.hpp
......@@ -128,6 +127,7 @@ cppa/util/apply_args.hpp
cppa/util/apply_tuple.hpp
cppa/util/arg_match_t.hpp
cppa/util/at.hpp
cppa/util/buffer.hpp
cppa/util/callable_trait.hpp
cppa/util/comparable.hpp
cppa/util/compare_tuples.hpp
......@@ -263,3 +263,6 @@ cppa/detail/ipv4_io_stream.hpp
src/ipv4_io_stream.cpp
cppa/detail/ipv4_acceptor.hpp
src/ipv4_acceptor.cpp
cppa/detail/middleman.hpp
src/middleman.cpp
src/buffer.cpp
......@@ -31,102 +31,118 @@
#ifndef CPPA_BUFFER_HPP
#define CPPA_BUFFER_HPP
#include <ios> // std::ios_base::failure
#include <cstring>
#include <iostream>
#include <cstddef> // size_t
#include "cppa/util/input_stream.hpp"
namespace cppa { namespace util {
namespace cppa { namespace detail {
class input_stream;
template<size_t ChunkSize, size_t MaxBufferSize>
class buffer {
enum buffer_write_policy {
grow_if_needed,
do_not_grow
};
char* m_data;
size_t m_written;
size_t m_allocated;
size_t m_final_size;
/**
*
*/
class buffer {
public:
buffer() : m_data(nullptr), m_written(0), m_allocated(0), m_final_size(0) {}
buffer();
buffer(buffer&& other)
: m_data(other.m_data), m_written(other.m_written)
, m_allocated(other.m_allocated), m_final_size(other.m_final_size) {
other.m_data = nullptr;
other.m_written = other.m_allocated = other.m_final_size = 0;
}
buffer(size_t chunk_size, size_t max_buffer_size);
~buffer() {
delete[] m_data;
}
buffer(buffer&& other);
void clear() {
m_written = 0;
}
buffer& operator=(buffer&& other);
void reset(size_t new_final_size = 0) {
if (new_final_size > MaxBufferSize) {
m_written = 0;
m_allocated = 0;
m_final_size = 0;
delete[] m_data;
m_data = nullptr;
throw std::ios_base::failure("maximum buffer size exceeded");
}
~buffer();
/**
* @brief Clears the buffer's content.
*/
inline void clear() {
m_written = 0;
m_final_size = new_final_size;
if (new_final_size > m_allocated) {
auto remainder = (new_final_size % ChunkSize);
if (remainder == 0) {
m_allocated = new_final_size;
}
else {
m_allocated = (new_final_size - remainder) + ChunkSize;
}
delete[] m_data;
m_data = new char[m_allocated];
}
}
// pointer to the current write position
char* wr_ptr() {
return m_data + m_written;
}
/**
* @brief Clears the buffer's content and sets the new final size to
* @p new_final_size.
*/
void reset(size_t new_final_size = 0);
/**
* @brief Makes sure the buffer can at least write @p num_bytes additional
* bytes and increases the final size if needed.
*/
void acquire(size_t num_bytes);
size_t size() {
void erase_leading(size_t num_bytes);
void erase_trailing(size_t num_bytes);
inline size_t size() const {
return m_written;
}
size_t final_size() {
inline size_t final_size() const {
return m_final_size;
}
size_t remaining() {
inline size_t remaining() const {
return m_final_size - m_written;
}
void inc_written(size_t value) {
m_written += value;
inline const char* data() const {
return m_data;
}
char* data() {
inline char* data() {
return m_data;
}
inline bool full() {
inline bool full() const {
return remaining() == 0;
}
void append_from(util::input_stream* istream) {
CPPA_REQUIRE(remaining() > 0);
auto num_bytes = istream->read_some(wr_ptr(), remaining());
if (num_bytes > 0) {
inc_written(num_bytes);
}
inline bool empty() const {
return size() == 0;
}
inline size_t maximum_size() const {
return m_max_buffer_size;
}
void write(size_t num_bytes, const void* data, buffer_write_policy wp);
/**
* @brief Appends up to @p remaining() bytes from @p istream to the buffer.
*/
void append_from(input_stream* istream);
private:
// pointer to the current write position
inline char* wr_ptr() {
return m_data + m_written;
}
inline void inc_size(size_t value) {
m_written += value;
}
inline void dec_size(size_t value) {
m_written -= value;
}
char* m_data;
size_t m_written;
size_t m_allocated;
size_t m_final_size;
size_t m_chunk_size;
size_t m_max_buffer_size;
};
} } // namespace cppa::detail
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include <ios> // std::ios_base::failure
#include <cstring>
#include <utility>
#include "cppa/util/buffer.hpp"
#include "cppa/util/input_stream.hpp"
namespace cppa { namespace util {
namespace {
const size_t default_chunk_size = 512;
const size_t default_max_size = 16 * 1024 * 1024;
} // namespace anonymous
buffer::buffer()
: m_data(0), m_written(0), m_allocated(0), m_final_size(0)
, m_chunk_size(default_chunk_size), m_max_buffer_size(default_max_size) { }
buffer::buffer(size_t chunk_size, size_t max_buffer_size)
: m_data(0), m_written(0), m_allocated(0), m_final_size(0)
, m_chunk_size(chunk_size), m_max_buffer_size(max_buffer_size) { }
buffer::buffer(buffer&& other)
: m_data(other.m_data), m_written(other.m_written)
, m_allocated(other.m_allocated), m_final_size(other.m_final_size)
, m_chunk_size(other.m_chunk_size), m_max_buffer_size(other.m_max_buffer_size) {
other.m_data = nullptr;
other.m_written = other.m_allocated = other.m_final_size = 0;
}
buffer& buffer::operator=(buffer&& other) {
std::swap(m_data, other.m_data);
std::swap(m_written, other.m_written);
std::swap(m_allocated, other.m_allocated);
std::swap(m_final_size, other.m_final_size);
std::swap(m_chunk_size, other.m_chunk_size);
std::swap(m_max_buffer_size, other.m_max_buffer_size);
return *this;
}
buffer::~buffer() {
delete[] m_data;
}
void buffer::reset(size_t new_final_size) {
if (new_final_size > m_max_buffer_size) {
m_written = 0;
m_allocated = 0;
m_final_size = 0;
delete[] m_data;
m_data = nullptr;
throw std::ios_base::failure("maximum buffer size exceeded");
}
m_written = 0;
m_final_size = new_final_size;
if (new_final_size > m_allocated) {
auto remainder = (new_final_size % m_chunk_size);
if (remainder == 0) {
m_allocated = new_final_size;
}
else {
m_allocated = (new_final_size - remainder) + m_chunk_size;
}
delete[] m_data;
m_data = new char[m_allocated];
}
}
void buffer::acquire(size_t num_bytes) {
if (!m_data) {
reset(num_bytes);
}
else if (remaining() < num_bytes) {
m_final_size += num_bytes - remaining();
if ((m_allocated - m_written) < num_bytes) {
auto remainder = (m_final_size % m_chunk_size);
if (remainder == 0) {
m_allocated = m_final_size;
}
else {
m_allocated = (m_final_size - remainder) + m_chunk_size;
}
auto old_data = m_data;
m_data = new char[m_allocated];
memcpy(m_data, old_data, m_written);
delete[] old_data;
}
}
}
void buffer::erase_leading(size_t num_bytes) {
if (num_bytes >= size()) {
clear();
}
else {
memmove(m_data, m_data + num_bytes, size() - num_bytes);
dec_size(num_bytes);
}
}
void buffer::erase_trailing(size_t num_bytes) {
if (num_bytes >= size()) {
clear();
}
else {
dec_size(num_bytes);
}
}
void buffer::write(size_t num_bytes, const void* data, buffer_write_policy wp) {
if (wp == grow_if_needed) {
acquire(num_bytes);
}
else if (num_bytes > remaining()) {
throw std::ios_base::failure("final buffer size exceeded");
}
memcpy(wr_ptr(), data, num_bytes);
inc_size(num_bytes);
}
void buffer::append_from(input_stream* istream) {
CPPA_REQUIRE(remaining() > 0);
auto num_bytes = istream->read_some(wr_ptr(), remaining());
if (num_bytes > 0) {
inc_size(num_bytes);
}
}
} } // namespace cppa::util
......@@ -56,12 +56,12 @@
#include "cppa/deserializer.hpp"
#include "cppa/binary_deserializer.hpp"
#include "cppa/util/buffer.hpp"
#include "cppa/util/acceptor.hpp"
#include "cppa/util/io_stream.hpp"
#include "cppa/util/input_stream.hpp"
#include "cppa/util/output_stream.hpp"
#include "cppa/detail/buffer.hpp"
#include "cppa/detail/mailman.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/post_office.hpp"
......@@ -267,7 +267,7 @@ class po_peer : public post_office_worker {
// caches uniform_typeid<addressed_message>()
const uniform_type_info* m_meta_msg;
// manages socket input
buffer<512, (16 * 1024 * 1024)> m_buf;
util::buffer m_buf;
public:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment