[thrift] Merge protocol/transport changes from tfb/www

Summary: Supporting the thrift_protocol extension.
  Relevant changesets are r66531, r66700, r66708
Reviewed By: mcslee
Test Plan: same code already runs in tfb trunk, php -l
Revert: svn


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665315 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/php/src/protocol/TBinaryProtocol.php b/lib/php/src/protocol/TBinaryProtocol.php
index 69723da..63b10bf 100644
--- a/lib/php/src/protocol/TBinaryProtocol.php
+++ b/lib/php/src/protocol/TBinaryProtocol.php
@@ -1,4 +1,5 @@
 <?php
+include_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
 
 /**
  * Copyright (c) 2006- Facebook
@@ -398,4 +399,19 @@
   }
 }
 
+/**
+ * Accelerated binary protocol: used in conjunction with the thrift_protocol
+ * extension for faster deserialization
+ */
+class TBinaryProtocolAccelerated extends TBinaryProtocol {
+  public function __construct($trans, $strictRead=false, $strictWrite=true) {
+    // If the transport doesn't implement putBack, wrap it in a
+    // TBufferedTransport (which does)
+    if (!method_exists($trans, 'putBack')) {
+      $trans = new TBufferedTransport($trans);
+    } 
+    parent::__construct($trans, $strictRead, $strictWrite);
+  }
+}
+
 ?>
diff --git a/lib/php/src/transport/TBufferedTransport.php b/lib/php/src/transport/TBufferedTransport.php
index 2ce47e3..4ed0737 100644
--- a/lib/php/src/transport/TBufferedTransport.php
+++ b/lib/php/src/transport/TBufferedTransport.php
@@ -77,24 +77,28 @@
     $this->transport_->close();
   }
 
-  public function readAll($len) {
-    return $this->transport_->readAll($len);
+  public function putBack($data) {
+    if (empty($this->rBuf_)) {
+      $this->rBuf_ = $data;
+    }
+    else {
+      $this->rBuf_ = ($data . $this->rBuf_);
+    }
   }
   
   public function read($len) {
-    // Methinks PHP is already buffering these for us
-    return $this->transport_->read($len);
+    if (empty($this->rBuf_)){
+      $this->rBuf_ = $this->transport_->read($this->rBufSize_);
+    }
 
-    if (strlen($this->rBuf_) >= $len) {
-      $ret = substr($this->rBuf_, 0, $len);
-      $this->rBuf_ = substr($this->rBuf_, $len);
+    if (strlen($this->rBuf_) <= $len) {
+      $ret = $this->rBuf_;
+      $this->rBuf_ = '';
       return $ret;
     }
 
-    $this->rBuf_ .= $this->transport_->read($this->rBufSize_);
-    $give = min(strlen($this->rBuf_), $len);
-    $ret = substr($this->rBuf_, 0, $give);
-    $this->rBuf_ = substr($this->rBuf_, $give);
+    $ret = substr($this->rBuf_, 0, $len);
+    $this->rBuf_ = substr($this->rBuf_, $len);
     return $ret;
   }
 
@@ -111,6 +115,7 @@
       $this->transport_->write($this->wBuf_);
       $this->wBuf_ = '';
     }
+    $this->transport_->flush();
   }
 
 }
diff --git a/lib/php/src/transport/TFramedTransport.php b/lib/php/src/transport/TFramedTransport.php
index 63f5b0f..5750d78 100644
--- a/lib/php/src/transport/TFramedTransport.php
+++ b/lib/php/src/transport/TFramedTransport.php
@@ -94,7 +94,7 @@
     }
 
     // Just return full buff
-    if ($len > strlen($this->rBuf_)) {
+    if ($len >= strlen($this->rBuf_)) {
       $out = $this->rBuf_;
       $this->rBuf_ = null;
       return $out;
@@ -107,6 +107,20 @@
   }
 
   /**
+   * Put previously read data back into the buffer
+   *
+   * @param string $data data to return
+   */
+  public function putBack($data) {
+    if (empty($this->rBuf_)) {
+      $this->rBuf_ = $data;
+    }
+    else {
+      $this->rBuf_ = ($data . $this->rBuf_);
+    }
+  }
+
+  /**
    * Reads a chunk of data into the internal read buffer.
    */
   private function readFrame() {
@@ -150,4 +164,4 @@
     $this->wBuf_ = '';
   }
 
-}
\ No newline at end of file
+}