THRIFT-922. cpp: Add shortcutted version of readAll() in TBufferBase

Just perform a memcpy() if all of the requested data is available in the
buffer.  This improves performance a little in the common case.  It has
a bigger impact with the upcoming template changes.

git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@1005133 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TBufferTransports.h b/lib/cpp/src/transport/TBufferTransports.h
index f81a6a0..dbe7aca 100644
--- a/lib/cpp/src/transport/TBufferTransports.h
+++ b/lib/cpp/src/transport/TBufferTransports.h
@@ -69,6 +69,19 @@
   }
 
   /**
+   * Shortcutted version of readAll.
+   */
+  uint32_t readAll(uint8_t* buf, uint32_t len) {
+    uint8_t* new_rBase = rBase_ + len;
+    if (TDB_LIKELY(new_rBase <= rBound_)) {
+      std::memcpy(buf, rBase_, len);
+      rBase_ = new_rBase;
+      return len;
+    }
+    return facebook::thrift::transport::readAll(*this, buf, len);
+  }
+
+  /**
    * Fast-path write.
    *
    * When we have enough empty space in our buffer to accomodate the write, we
diff --git a/lib/cpp/src/transport/TTransport.h b/lib/cpp/src/transport/TTransport.h
index 7417c87..c453b8e 100644
--- a/lib/cpp/src/transport/TTransport.h
+++ b/lib/cpp/src/transport/TTransport.h
@@ -28,6 +28,27 @@
 namespace apache { namespace thrift { namespace transport {
 
 /**
+ * Helper template to hoist readAll implementation out of TTransport
+ */
+template <class Transport_>
+uint32_t readAll(Transport_ &trans, uint8_t* buf, uint32_t len) {
+  uint32_t have = 0;
+  uint32_t get = 0;
+
+  while (have < len) {
+    get = trans.read(buf+have, len-have);
+    if (get <= 0) {
+      throw TTransportException(TTransportException::END_OF_FILE,
+                                "No more data to read.");
+    }
+    have += get;
+  }
+
+  return have;
+}
+
+
+/**
  * Generic interface for a method of transporting data. A TTransport may be
  * capable of either reading or writing, but not necessarily both.
  *
@@ -96,19 +117,7 @@
    * @throws TTransportException If insufficient data was read
    */
   virtual uint32_t readAll(uint8_t* buf, uint32_t len) {
-    uint32_t have = 0;
-    uint32_t get = 0;
-
-    while (have < len) {
-      get = read(buf+have, len-have);
-      if (get <= 0) {
-        throw TTransportException(TTransportException::END_OF_FILE,
-				  "No more data to read.");
-      }
-      have += get;
-    }
-
-    return have;
+    return apache::thrift::transport::readAll(*this, buf, len);
   }
 
   /**