/* */ #include "SocketBuffer.h" #include #include #include "SocketCore.h" #include "DlAbortEx.h" #include "message.h" #include "fmt.h" 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) {} SocketBuffer::StringBufEntry::StringBufEntry() {} 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; } void SocketBuffer::StringBufEntry::swap(std::string& s) { str_.swap(s); } SocketBuffer::SocketBuffer(const SharedHandle& socket): socket_(socket), offset_(0) {} SocketBuffer::~SocketBuffer() {} void SocketBuffer::pushBytes(unsigned char* bytes, size_t len) { if(len > 0) { bufq_.push_back(SharedHandle(new ByteArrayBufEntry(bytes, len))); } } void SocketBuffer::pushStr(const std::string& data) { if(data.size() > 0) { bufq_.push_back(SharedHandle(new StringBufEntry(data))); } } ssize_t SocketBuffer::send() { size_t totalslen = 0; while(!bufq_.empty()) { 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; offset_ += slen; if(buf->final(offset_)) { bufq_.pop_front(); offset_ = 0; } else { break; } } return totalslen; } bool SocketBuffer::sendBufferIsEmpty() const { return bufq_.empty(); } } // namespace aria2