From 3d2fa5954e91a9e8aa1561a21ac7750e5717c3ad Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Fri, 18 Mar 2011 17:20:37 +0900 Subject: [PATCH] Rewritten SocketBuffer::BufEntry and SocketBuffer::send() --- src/SocketBuffer.cc | 80 ++++++++++++++++++++++++++++----------------- src/SocketBuffer.h | 59 +++++++++++++++------------------ 2 files changed, 77 insertions(+), 62 deletions(-) diff --git a/src/SocketBuffer.cc b/src/SocketBuffer.cc index beeee2df..010ba984 100644 --- a/src/SocketBuffer.cc +++ b/src/SocketBuffer.cc @@ -44,57 +44,77 @@ namespace aria2 { +SocketBuffer::ByteArrayBufEntry::ByteArrayBufEntry +(unsigned char* bytes, size_t length) + : bytes_(bytes), length_(length) +{} + +SocketBuffer::ByteArrayBufEntry::~ByteArrayBufEntry() +{ + delete [] bytes_; +} + +ssize_t SocketBuffer::ByteArrayBufEntry::send +(const SharedHandle& socket, size_t offset) +{ + return socket->writeData(bytes_+offset, length_-offset); +} + +bool SocketBuffer::ByteArrayBufEntry::final(size_t offset) const +{ + return length_ <= offset; +} + +SocketBuffer::StringBufEntry::StringBufEntry(const std::string& s) + : str_(s) +{} + +ssize_t SocketBuffer::StringBufEntry::send +(const SharedHandle& socket, size_t offset) +{ + return socket->writeData(str_.data()+offset, str_.size()-offset); +} + +bool SocketBuffer::StringBufEntry::final(size_t offset) const +{ + return str_.size() <= offset; +} + SocketBuffer::SocketBuffer(const SharedHandle& socket): socket_(socket), offset_(0) {} -SocketBuffer::~SocketBuffer() -{ - std::for_each(bufq_.begin(), bufq_.end(), - std::mem_fun_ref(&BufEntry::deleteBuf)); -} +SocketBuffer::~SocketBuffer() {} void SocketBuffer::pushBytes(unsigned char* bytes, size_t len) { - bufq_.push_back(BufEntry(bytes, len)); + if(len > 0) { + bufq_.push_back(SharedHandle(new ByteArrayBufEntry(bytes, len))); + } } void SocketBuffer::pushStr(const std::string& data) { - bufq_.push_back(BufEntry(data)); + if(data.size() > 0) { + bufq_.push_back(SharedHandle(new StringBufEntry(data))); + } } ssize_t SocketBuffer::send() { size_t totalslen = 0; while(!bufq_.empty()) { - BufEntry& buf = bufq_[0]; - if(buf.size() == 0) { - buf.deleteBuf(); - bufq_.pop_front(); - continue; - } - const char* data; - ssize_t r; - if(buf.type == TYPE_BYTES) { - data = reinterpret_cast(buf.bytes); - r = buf.bytesLen-offset_; - } else { - const std::string& str = *buf.str; - data = str.data(); - r = str.size()-offset_; - } - ssize_t slen = socket_->writeData(data+offset_, r); + const SharedHandle& buf = bufq_[0]; + ssize_t slen = buf->send(socket_, offset_); if(slen == 0 && !socket_->wantRead() && !socket_->wantWrite()) { throw DL_ABORT_EX(fmt(EX_SOCKET_SEND, "Connection closed.")); } totalslen += slen; - if(slen < r) { - offset_ += slen; - break; - } else { - offset_ = 0; - buf.deleteBuf(); + offset_ += slen; + if(buf->final(offset_)) { bufq_.pop_front(); + offset_ = 0; + } else { + break; } } return totalslen; diff --git a/src/SocketBuffer.h b/src/SocketBuffer.h index 791703eb..f2baeb49 100644 --- a/src/SocketBuffer.h +++ b/src/SocketBuffer.h @@ -48,44 +48,39 @@ class SocketCore; class SocketBuffer { private: - enum BUF_TYPE { - TYPE_BYTES, - TYPE_STR + class BufEntry { + public: + virtual ~BufEntry() {} + virtual ssize_t send + (const SharedHandle& socket, size_t offset) = 0; + virtual bool final(size_t offset) const = 0; }; - struct BufEntry { - BUF_TYPE type; - unsigned char* bytes; - size_t bytesLen; - std::string* str; - void deleteBuf() - { - if(type == TYPE_BYTES) { - delete [] bytes; - } else if(type == TYPE_STR) { - delete str; - } - } - - size_t size() const - { - if(type == TYPE_BYTES) { - return bytesLen; - } else { - return str->size(); - } - } + class ByteArrayBufEntry:public BufEntry { + public: + ByteArrayBufEntry(unsigned char* bytes, size_t length); + virtual ~ByteArrayBufEntry(); + virtual ssize_t send + (const SharedHandle& socket, size_t offset); + virtual bool final(size_t offset) const; + private: + unsigned char* bytes_; + size_t length_; + }; - BufEntry(unsigned char* bytes, size_t len): - type(TYPE_BYTES), bytes(bytes), bytesLen(len) {} - - BufEntry(const std::string& str): - type(TYPE_STR), str(new std::string(str)) {} + class StringBufEntry:public BufEntry { + public: + StringBufEntry(const std::string& s); + virtual ssize_t send + (const SharedHandle& socket, size_t offset); + virtual bool final(size_t offset) const; + private: + std::string str_; }; SharedHandle socket_; - std::deque bufq_; + std::deque > bufq_; // Offset of data in bufq_[0]. SocketBuffer tries to send bufq_[0], // but it cannot always send whole data. In this case, offset points @@ -100,7 +95,7 @@ public: SocketBuffer(const SocketBuffer&); SocketBuffer& operator=(const SocketBuffer&); - // Feeds data pointered by bytes with length len. into queue. This + // Feeds data pointered by bytes with length len into queue. This // object gets ownership of bytes, so caller must not delete or // later bytes after this call. This function doesn't send data. void pushBytes(unsigned char* bytes, size_t len);