SocketBuffer: Use std::unique_ptr to store BufEntry

pull/103/head
Tatsuhiro Tsujikawa 2013-06-23 23:06:12 +09:00
parent c0b60eb087
commit 508109edbb
2 changed files with 26 additions and 24 deletions

View File

@ -42,6 +42,7 @@
#include "message.h" #include "message.h"
#include "fmt.h" #include "fmt.h"
#include "LogFactory.h" #include "LogFactory.h"
#include "a2functional.h"
namespace aria2 { namespace aria2 {
@ -76,9 +77,9 @@ const unsigned char* SocketBuffer::ByteArrayBufEntry::getData() const
return bytes_; return bytes_;
} }
SocketBuffer::StringBufEntry::StringBufEntry(const std::string& s, SocketBuffer::StringBufEntry::StringBufEntry(std::string s,
ProgressUpdate* progressUpdate) ProgressUpdate* progressUpdate)
: BufEntry(progressUpdate), str_(s) : BufEntry(progressUpdate), str_(std::move(s))
{} {}
// SocketBuffer::StringBufEntry::StringBufEntry() {} // SocketBuffer::StringBufEntry::StringBufEntry() {}
@ -118,17 +119,16 @@ void SocketBuffer::pushBytes(unsigned char* bytes, size_t len,
ProgressUpdate* progressUpdate) ProgressUpdate* progressUpdate)
{ {
if(len > 0) { if(len > 0) {
bufq_.push_back(std::shared_ptr<BufEntry> bufq_.push_back(make_unique<ByteArrayBufEntry>(bytes, len,
(new ByteArrayBufEntry(bytes, len, progressUpdate))); progressUpdate));
} }
} }
void SocketBuffer::pushStr(const std::string& data, void SocketBuffer::pushStr(std::string data, ProgressUpdate* progressUpdate)
ProgressUpdate* progressUpdate)
{ {
if(data.size() > 0) { if(!data.empty()) {
bufq_.push_back(std::shared_ptr<BufEntry> bufq_.push_back(make_unique<StringBufEntry>(std::move(data),
(new StringBufEntry(data, progressUpdate))); progressUpdate));
} }
} }
@ -138,21 +138,23 @@ ssize_t SocketBuffer::send()
size_t totalslen = 0; size_t totalslen = 0;
while(!bufq_.empty()) { while(!bufq_.empty()) {
size_t num; size_t num;
size_t bufqlen = bufq_.size();
ssize_t amount = 24*1024; ssize_t amount = 24*1024;
ssize_t firstlen = bufq_[0]->getLength() - offset_; ssize_t firstlen = bufq_.front()->getLength() - offset_;
amount -= firstlen; amount -= firstlen;
iov[0].A2IOVEC_BASE = iov[0].A2IOVEC_BASE =
reinterpret_cast<char*>(const_cast<unsigned char*> reinterpret_cast<char*>(const_cast<unsigned char*>
(bufq_[0]->getData() + offset_)); (bufq_.front()->getData() + offset_));
iov[0].A2IOVEC_LEN = firstlen; iov[0].A2IOVEC_LEN = firstlen;
num = 1;
for(num = 1; num < A2_IOV_MAX && num < bufq_.size() && amount > 0; ++num) { for(auto i = std::begin(bufq_)+1, eoi = std::end(bufq_);
const std::shared_ptr<BufEntry>& buf = bufq_[num]; i != eoi && num < A2_IOV_MAX && num < bufqlen && amount > 0;
ssize_t len = buf->getLength(); ++i, ++num) {
ssize_t len = (*i)->getLength();
if(amount >= len) { if(amount >= len) {
amount -= len; amount -= len;
iov[num].A2IOVEC_BASE = iov[num].A2IOVEC_BASE =
reinterpret_cast<char*>(const_cast<unsigned char*>(buf->getData())); reinterpret_cast<char*>(const_cast<unsigned char*>((*i)->getData()));
iov[num].A2IOVEC_LEN = len; iov[num].A2IOVEC_LEN = len;
} else { } else {
break; break;
@ -168,24 +170,24 @@ ssize_t SocketBuffer::send()
if(firstlen > slen) { if(firstlen > slen) {
offset_ += slen; offset_ += slen;
bufq_[0]->progressUpdate(slen, false); bufq_.front()->progressUpdate(slen, false);
goto fin; goto fin;
} else { } else {
slen -= firstlen; slen -= firstlen;
bufq_[0]->progressUpdate(firstlen, true); bufq_.front()->progressUpdate(firstlen, true);
bufq_.pop_front(); bufq_.pop_front();
offset_ = 0; offset_ = 0;
for(size_t i = 1; i < num; ++i) { for(size_t i = 1; i < num; ++i) {
const std::shared_ptr<BufEntry>& buf = bufq_[0]; const std::unique_ptr<BufEntry>& buf = bufq_.front();
ssize_t len = buf->getLength(); ssize_t len = buf->getLength();
if(len > slen) { if(len > slen) {
offset_ = slen; offset_ = slen;
bufq_[0]->progressUpdate(slen, false); bufq_.front()->progressUpdate(slen, false);
goto fin; goto fin;
break; break;
} else { } else {
slen -= len; slen -= len;
bufq_[0]->progressUpdate(len, true); bufq_.front()->progressUpdate(len, true);
bufq_.pop_front(); bufq_.pop_front();
} }
} }

View File

@ -92,7 +92,7 @@ private:
class StringBufEntry:public BufEntry { class StringBufEntry:public BufEntry {
public: public:
StringBufEntry(const std::string& s, StringBufEntry(std::string s,
ProgressUpdate* progressUpdate); ProgressUpdate* progressUpdate);
StringBufEntry(); StringBufEntry();
virtual ssize_t send virtual ssize_t send
@ -107,7 +107,7 @@ private:
std::shared_ptr<SocketCore> socket_; std::shared_ptr<SocketCore> socket_;
std::deque<std::shared_ptr<BufEntry> > bufq_; std::deque<std::unique_ptr<BufEntry> > bufq_;
// Offset of data in bufq_[0]. SocketBuffer tries to send bufq_[0], // Offset of data in bufq_[0]. SocketBuffer tries to send bufq_[0],
// but it cannot always send whole data. In this case, offset points // but it cannot always send whole data. In this case, offset points
@ -135,7 +135,7 @@ public:
// progressUpdate is not null, its update() function will be called // progressUpdate is not null, its update() function will be called
// each time the data is sent. It will be deleted by this object. It // each time the data is sent. It will be deleted by this object. It
// can be null. // can be null.
void pushStr(const std::string& data, ProgressUpdate* progressUpdate = 0); void pushStr(std::string data, ProgressUpdate* progressUpdate = 0);
// Sends data in queue. Returns the number of bytes sent. // Sends data in queue. Returns the number of bytes sent.
ssize_t send(); ssize_t send();