瀏覽代碼

Rewritten SocketBuffer::BufEntry and SocketBuffer::send()

Tatsuhiro Tsujikawa 14 年之前
父節點
當前提交
3d2fa5954e
共有 2 個文件被更改,包括 79 次插入64 次删除
  1. 50 30
      src/SocketBuffer.cc
  2. 29 34
      src/SocketBuffer.h

+ 50 - 30
src/SocketBuffer.cc

@@ -44,57 +44,77 @@
 
 namespace aria2 {
 
-SocketBuffer::SocketBuffer(const SharedHandle<SocketCore>& socket):
-  socket_(socket), offset_(0) {}
+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<SocketCore>& socket, size_t offset)
+{
+  return socket->writeData(bytes_+offset, length_-offset);
+}
 
-SocketBuffer::~SocketBuffer()
+bool SocketBuffer::ByteArrayBufEntry::final(size_t offset) const
 {
-  std::for_each(bufq_.begin(), bufq_.end(),
-                std::mem_fun_ref(&BufEntry::deleteBuf));
+  return length_ <= offset;
 }
 
+SocketBuffer::StringBufEntry::StringBufEntry(const std::string& s)
+  : str_(s)
+{}
+
+ssize_t SocketBuffer::StringBufEntry::send
+(const SharedHandle<SocketCore>& 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<SocketCore>& socket):
+  socket_(socket), offset_(0) {}
+
+SocketBuffer::~SocketBuffer() {}
+
 void SocketBuffer::pushBytes(unsigned char* bytes, size_t len)
 {
-  bufq_.push_back(BufEntry(bytes, len));
+  if(len > 0) {
+    bufq_.push_back(SharedHandle<BufEntry>(new ByteArrayBufEntry(bytes, len)));
+  }
 }
 
 void SocketBuffer::pushStr(const std::string& data)
 {
-  bufq_.push_back(BufEntry(data));
+  if(data.size() > 0) {
+    bufq_.push_back(SharedHandle<BufEntry>(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<const char*>(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<BufEntry>& 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;

+ 29 - 34
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<SocketCore>& 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();
-      }
-    }
-
-    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 ByteArrayBufEntry:public BufEntry {
+  public:
+    ByteArrayBufEntry(unsigned char* bytes, size_t length);
+    virtual ~ByteArrayBufEntry();
+    virtual ssize_t send
+    (const SharedHandle<SocketCore>& socket, size_t offset);
+    virtual bool final(size_t offset) const;
+  private:
+    unsigned char* bytes_;
+    size_t length_;
+  };
+
+  class StringBufEntry:public BufEntry {
+  public:
+    StringBufEntry(const std::string& s);
+    virtual ssize_t send
+    (const SharedHandle<SocketCore>& socket, size_t offset);
+    virtual bool final(size_t offset) const;
+  private:
+    std::string str_;
   };
     
   SharedHandle<SocketCore> socket_;
 
-  std::deque<BufEntry> bufq_;
+  std::deque<SharedHandle<BufEntry> > 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);