Lazily allocate input buffer for AsyncTCPSocket.

As a follow-up to https://codereview.webrtc.org/1737053006/ this CL further
improves memory usage by lazily allocating input buffers up to the passed
maximum size. This also changes the input buffer to a Buffer object.

BUG=

Review URL: https://codereview.webrtc.org/1744293002

Cr-Commit-Position: refs/heads/master@{#11859}
diff --git a/webrtc/base/asynctcpsocket.cc b/webrtc/base/asynctcpsocket.cc
index 31dec92..65ec0f2 100644
--- a/webrtc/base/asynctcpsocket.cc
+++ b/webrtc/base/asynctcpsocket.cc
@@ -12,6 +12,8 @@
 
 #include <string.h>
 
+#include <algorithm>
+
 #include "webrtc/base/byteorder.h"
 #include "webrtc/base/checks.h"
 #include "webrtc/base/common.h"
@@ -30,6 +32,11 @@
 
 static const size_t kBufSize = kMaxPacketSize + kPacketLenSize;
 
+// The input buffer will be resized so that at least kMinimumRecvSize bytes can
+// be received (but it will not grow above the maximum size passed to the
+// constructor).
+static const size_t kMinimumRecvSize = 128;
+
 static const int kListenBacklog = 5;
 
 // Binds and connects |socket|
@@ -53,12 +60,11 @@
                                        size_t max_packet_size)
     : socket_(socket),
       listen_(listen),
-      insize_(max_packet_size),
-      inpos_(0),
+      max_insize_(max_packet_size),
       max_outsize_(max_packet_size) {
   if (!listen_) {
     // Listening sockets don't send/receive data, so they don't need buffers.
-    inbuf_.reset(new char[insize_]);
+    inbuf_.EnsureCapacity(kMinimumRecvSize);
   }
 
   RTC_DCHECK(socket_.get() != NULL);
@@ -182,7 +188,7 @@
     rtc::SocketAddress address;
     rtc::AsyncSocket* new_socket = socket->Accept(&address);
     if (!new_socket) {
-      // TODO: Do something better like forwarding the error
+      // TODO(stefan): Do something better like forwarding the error
       // to the user.
       LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError();
       return;
@@ -193,24 +199,44 @@
     // Prime a read event in case data is waiting.
     new_socket->SignalReadEvent(new_socket);
   } else {
-    RTC_DCHECK(inbuf_.get());
-    int len = socket_->Recv(inbuf_.get() + inpos_, insize_ - inpos_);
-    if (len < 0) {
-      // TODO: Do something better like forwarding the error to the user.
-      if (!socket_->IsBlocking()) {
-        LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError();
+    size_t total_recv = 0;
+    while (true) {
+      size_t free_size = inbuf_.capacity() - inbuf_.size();
+      if (free_size < kMinimumRecvSize && inbuf_.capacity() < max_insize_) {
+        inbuf_.EnsureCapacity(std::min(max_insize_, inbuf_.capacity() * 2));
+        free_size = inbuf_.capacity() - inbuf_.size();
       }
+
+      int len = socket_->Recv(inbuf_.data() + inbuf_.size(), free_size);
+      if (len < 0) {
+        // TODO(stefan): Do something better like forwarding the error to the
+        // user.
+        if (!socket_->IsBlocking()) {
+          LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError();
+        }
+        break;
+      }
+
+      total_recv += len;
+      inbuf_.SetSize(inbuf_.size() + len);
+      if (!len || static_cast<size_t>(len) < free_size) {
+        break;
+      }
+    }
+
+    if (!total_recv) {
       return;
     }
 
-    inpos_ += len;
+    size_t size = inbuf_.size();
+    ProcessInput(inbuf_.data<char>(), &size);
 
-    ProcessInput(inbuf_.get(), &inpos_);
-
-    if (inpos_ >= insize_) {
+    if (size > inbuf_.size()) {
       LOG(LS_ERROR) << "input buffer overflow";
       RTC_NOTREACHED();
-      inpos_ = 0;
+      inbuf_.Clear();
+    } else {
+      inbuf_.SetSize(size);
     }
   }
 }