123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- /*
- * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
- *
- * This file is part of ZLToolKit(https://github.com/xia-chu/ZLToolKit).
- *
- * Use of this source code is governed by MIT license that can be found in the
- * LICENSE file in the root of the source tree. All contributing project authors
- * may be found in the AUTHORS file in the root of the source tree.
- */
- #ifndef ZLTOOLKIT_BUFFER_H
- #define ZLTOOLKIT_BUFFER_H
- #include <assert.h>
- #include <memory>
- #include <string>
- #include <deque>
- #include <mutex>
- #include <vector>
- #include <atomic>
- #include <sstream>
- #include <type_traits>
- #include <functional>
- #include "Util/util.h"
- #include "Util/List.h"
- #include "Util/uv_errno.h"
- #include "Util/ResourcePool.h"
- #include "Network/sockutil.h"
- using namespace std;
- namespace toolkit {
- template <typename T> struct is_pointer : public std::false_type {};
- template <typename T> struct is_pointer<shared_ptr<T> > : public std::true_type {};
- template <typename T> struct is_pointer<shared_ptr<T const> > : public std::true_type {};
- template <typename T> struct is_pointer<T*> : public true_type {};
- template <typename T> struct is_pointer<const T*> : public true_type {};
- //缓存基类
- class Buffer : public noncopyable {
- public:
- typedef std::shared_ptr<Buffer> Ptr;
- Buffer(){};
- virtual ~Buffer(){};
- //返回数据长度
- virtual char *data() const = 0 ;
- virtual size_t size() const = 0;
- virtual string toString() const {
- return string(data(),size());
- }
- virtual size_t getCapacity() const{
- return size();
- }
- private:
- //对象个数统计
- ObjectStatistic<Buffer> _statistic;
- };
- template <typename C>
- class BufferOffset : public Buffer {
- public:
- typedef std::shared_ptr<BufferOffset> Ptr;
- BufferOffset(C data, size_t offset = 0, size_t len = 0) : _data(std::move(data)) {
- setup(offset, len);
- }
- ~BufferOffset() {}
- char *data() const override {
- return const_cast<char *>(getPointer<C>(_data)->data()) + _offset;
- }
- size_t size() const override{
- return _size;
- }
- string toString() const override {
- return string(data(),size());
- }
- private:
- void setup(size_t offset = 0, size_t size = 0) {
- auto max_size = getPointer<C>(_data)->size();
- assert(offset + size <= max_size);
- if (!size) {
- size = max_size - offset;
- }
- _size = size;
- _offset = offset;
- }
- template<typename T>
- static typename std::enable_if<toolkit::is_pointer<T>::value, const T &>::type
- getPointer(const T &data) {
- return data;
- }
- template<typename T>
- static typename std::enable_if<!toolkit::is_pointer<T>::value, const T *>::type
- getPointer(const T &data) {
- return &data;
- }
- private:
- C _data;
- size_t _offset;
- size_t _size;
- };
- typedef BufferOffset<string> BufferString;
- //指针式缓存对象,
- class BufferRaw : public Buffer{
- public:
- using Ptr = std::shared_ptr<BufferRaw>;
- static Ptr create();
- ~BufferRaw() override{
- if(_data){
- delete [] _data;
- }
- }
- //在写入数据时请确保内存是否越界
- char *data() const override {
- return _data;
- }
- //有效数据大小
- size_t size() const override{
- return _size;
- }
- //分配内存大小
- void setCapacity(size_t capacity){
- if(_data){
- do{
- if(capacity > _capacity){
- //请求的内存大于当前内存,那么重新分配
- break;
- }
- if(_capacity < 2 * 1024){
- //2K以下,不重复开辟内存,直接复用
- return;
- }
- if(2 * capacity > _capacity){
- //如果请求的内存大于当前内存的一半,那么也复用
- return;
- }
- }while(false);
- delete [] _data;
- }
- _data = new char[capacity];
- _capacity = capacity;
- }
- //设置有效数据大小
- void setSize(size_t size){
- if(size > _capacity){
- throw std::invalid_argument("Buffer::setSize out of range");
- }
- _size = size;
- }
- //赋值数据
- void assign(const char *data,size_t size = 0){
- if(size <=0 ){
- size = strlen(data);
- }
- setCapacity(size + 1);
- memcpy(_data,data,size);
- _data[size] = '\0';
- setSize(size);
- }
- size_t getCapacity() const override{
- return _capacity;
- }
- protected:
- friend class ResourcePool_l<BufferRaw>;
- BufferRaw(size_t capacity = 0) {
- if(capacity){
- setCapacity(capacity);
- }
- }
- BufferRaw(const char *data,size_t size = 0){
- assign(data,size);
- }
- private:
- size_t _size = 0;
- size_t _capacity = 0;
- char *_data = nullptr;
- //对象个数统计
- ObjectStatistic<BufferRaw> _statistic;
- };
- class BufferLikeString : public Buffer {
- public:
- ~BufferLikeString() override {}
- BufferLikeString() {
- _erase_head = 0;
- _erase_tail = 0;
- }
- BufferLikeString(string str) {
- _str = std::move(str);
- _erase_head = 0;
- _erase_tail = 0;
- }
- BufferLikeString& operator= (string str){
- _str = std::move(str);
- _erase_head = 0;
- _erase_tail = 0;
- return *this;
- }
- BufferLikeString(const char *str) {
- _str = str;
- _erase_head = 0;
- _erase_tail = 0;
- }
- BufferLikeString& operator= (const char *str){
- _str = str;
- _erase_head = 0;
- _erase_tail = 0;
- return *this;
- }
- BufferLikeString(BufferLikeString &&that) {
- _str = std::move(that._str);
- _erase_head = that._erase_head;
- _erase_tail = that._erase_tail;
- that._erase_head = 0;
- that._erase_tail = 0;
- }
- BufferLikeString& operator= (BufferLikeString &&that){
- _str = std::move(that._str);
- _erase_head = that._erase_head;
- _erase_tail = that._erase_tail;
- that._erase_head = 0;
- that._erase_tail = 0;
- return *this;
- }
- BufferLikeString(const BufferLikeString &that) {
- _str = that._str;
- _erase_head = that._erase_head;
- _erase_tail = that._erase_tail;
- }
- BufferLikeString& operator= (const BufferLikeString &that){
- _str = that._str;
- _erase_head = that._erase_head;
- _erase_tail = that._erase_tail;
- return *this;
- }
- char* data() const override{
- return (char *)_str.data() + _erase_head;
- }
- size_t size() const override{
- return _str.size() - _erase_tail - _erase_head;
- }
- BufferLikeString& erase(size_t pos = 0, size_t n = string::npos) {
- if (pos == 0) {
- //移除前面的数据
- if (n != string::npos) {
- //移除部分
- if (n > size()) {
- //移除太多数据了
- throw std::out_of_range("BufferLikeString::erase out_of_range in head");
- }
- //设置起始便宜量
- _erase_head += n;
- data()[size()] = '\0';
- return *this;
- }
- //移除全部数据
- _erase_head = 0;
- _erase_tail = _str.size();
- data()[0] = '\0';
- return *this;
- }
- if (n == string::npos || pos + n >= size()) {
- //移除末尾所有数据
- if (pos >= size()) {
- //移除太多数据
- throw std::out_of_range("BufferLikeString::erase out_of_range in tail");
- }
- _erase_tail += size() - pos;
- data()[size()] = '\0';
- return *this;
- }
- //移除中间的
- if (pos + n > size()) {
- //超过长度限制
- throw std::out_of_range("BufferLikeString::erase out_of_range in middle");
- }
- _str.erase(_erase_head + pos, n);
- return *this;
- }
- BufferLikeString& append(const BufferLikeString &str){
- return append(str.data(), str.size());
- }
- BufferLikeString& append(const string &str){
- return append(str.data(), str.size());
- }
- BufferLikeString& append(const char *data){
- return append(data, strlen(data));
- }
- BufferLikeString& append(const char *data, size_t len){
- if (len <= 0) {
- return *this;
- }
- if (_erase_head > _str.capacity() / 2) {
- moveData();
- }
- if (_erase_tail == 0) {
- _str.append(data, len);
- return *this;
- }
- _str.insert(_erase_head + size(), data, len);
- return *this;
- }
- void push_back(char c){
- if(_erase_tail == 0){
- _str.push_back(c);
- return;
- }
- data()[size()] = c;
- --_erase_tail;
- data()[size()] = '\0';
- }
- BufferLikeString& insert(size_t pos, const char* s, size_t n){
- _str.insert(_erase_head + pos, s, n);
- return *this;
- }
- BufferLikeString& assign(const char *data) {
- return assign(data, strlen(data));
- }
- BufferLikeString& assign(const char *data, size_t len) {
- if (len <= 0) {
- return *this;
- }
- if (data >= _str.data() && data < _str.data() + _str.size()) {
- _erase_head = data - _str.data();
- if (data + len > _str.data() + _str.size()) {
- throw std::out_of_range("BufferLikeString::assign out_of_range");
- }
- _erase_tail = _str.data() + _str.size() - (data + len);
- return *this;
- }
- _str.assign(data, len);
- _erase_head = 0;
- _erase_tail = 0;
- return *this;
- }
- void clear() {
- _erase_head = 0;
- _erase_tail = 0;
- _str.clear();
- }
- char& operator[](size_t pos){
- if (pos >= size()) {
- throw std::out_of_range("BufferLikeString::operator[] out_of_range");
- }
- return data()[pos];
- }
- const char& operator[](size_t pos) const{
- return (*const_cast<BufferLikeString *>(this))[pos];
- }
- size_t capacity() const{
- return _str.capacity();
- }
- void reserve(size_t size){
- _str.reserve(size);
- }
- bool empty() const{
- return size() <= 0;
- }
- string substr(size_t pos, size_t n = string::npos) const{
- if (n == string::npos) {
- //获取末尾所有的
- if (pos >= size()) {
- throw std::out_of_range("BufferLikeString::substr out_of_range");
- }
- return _str.substr(_erase_head + pos, size() - pos);
- }
- //获取部分
- if (pos + n > size()) {
- throw std::out_of_range("BufferLikeString::substr out_of_range");
- }
- return _str.substr(_erase_head + pos, n);
- }
- private:
- void moveData(){
- if (_erase_head) {
- _str.erase(0, _erase_head);
- _erase_head = 0;
- }
- }
- private:
- size_t _erase_head;
- size_t _erase_tail;
- string _str;
- //对象个数统计
- ObjectStatistic<BufferLikeString> _statistic;
- };
- #if defined(_WIN32)
- struct iovec {
- void * iov_base; /* [XSI] Base address of I/O memory region */
- size_t iov_len; /* [XSI] Size of region iov_base points to */
- };
- struct msghdr {
- void *msg_name; /* [XSI] optional address */
- size_t msg_namelen; /* [XSI] size of address */
- struct iovec *msg_iov; /* [XSI] scatter/gather array */
- size_t msg_iovlen; /* [XSI] # elements in msg_iov */
- void *msg_control; /* [XSI] ancillary data, see below */
- int msg_controllen; /* [XSI] ancillary data buffer len */
- int msg_flags; /* [XSI] flags on received message */
- };
- #else
- #include <sys/uio.h>
- #include <limits.h>
- #endif
- #if !defined(IOV_MAX)
- #define IOV_MAX 1024
- #endif
- class BufferList;
- class BufferSock : public Buffer {
- public:
- using Ptr = std::shared_ptr<BufferSock>;
- friend class BufferList;
- BufferSock(Buffer::Ptr ptr, struct sockaddr *addr = nullptr, int addr_len = 0);
- ~BufferSock();
- char *data() const override;
- size_t size() const override;
- private:
- int _addr_len = 0;
- struct sockaddr *_addr = nullptr;
- Buffer::Ptr _buffer;
- };
- class BufferList : public noncopyable {
- public:
- using Ptr = std::shared_ptr<BufferList>;
- using SendResult = function<void(const Buffer::Ptr &buffer, bool send_success)>;
- BufferList(List<std::pair<Buffer::Ptr, bool> > &list, SendResult cb = nullptr);
- ~BufferList();
- bool empty();
- size_t count();
- ssize_t send(int fd, int flags, bool udp);
- private:
- void reOffset(size_t n);
- ssize_t send_l(int fd, int flags, bool udp);
- private:
- size_t _iovec_off = 0;
- size_t _remain_size = 0;
- vector<struct iovec> _iovec;
- List<std::pair<Buffer::Ptr, bool> > _pkt_list;
- SendResult _cb;
- //对象个数统计
- ObjectStatistic<BufferList> _statistic;
- };
- }//namespace toolkit
- #endif //ZLTOOLKIT_BUFFER_H
|