/** * Read some data into the array. * * @param int $len How much to read * @return string The data that has been read * @throws TTransportException if cannot read any more data */ public function read($len) { if (strlen($this->rbuffer_) > 0) { $ret = substr($this->rbuffer_, 0, $len); $this->rbuffer_ = substr($this->rbuffer_, $len); return $ret; } $data = $this->transport_->readAll(4); $array = unpack('Nlength', $data); $length = $array['length']; $this->rbuffer_ = $this->transport_->readAll($length); $ret = substr($this->rbuffer_, 0, $len); $this->rbuffer_ = substr($this->rbuffer_, $len); return $ret; }
/** * Reads a chunk of data into the internal read buffer. */ private function readFrame() { $buf = $this->transport_->readAll(4); $val = unpack('N', $buf); $sz = $val[1]; $this->rBuf_ = $this->transport_->readAll($sz); }
/** * Peek some bytes in the buffer without removing the bytes from it * * @param int $len length to peek * @param int $start the start position of the returned string * * @return null on peek failure */ public function peek($len, $start = 0) { $bytes_needed = $len + $start; // read until either timeout OR get enough bytes if (strlen($this->rBuf_) == 0) { $this->rBuf_ = $this->transport_->readAll($bytes_needed); } else { if ($bytes_needed > strlen($this->rBuf_)) { $this->rBuf_ .= $this->transport_->readAll($bytes_needed - strlen($this->rBuf_)); } } $ret = substr($this->rBuf_, $start, $len); return $ret; }
/** * The reason that we customize readAll here is that the majority of PHP * streams are already internally buffered by PHP. The socket stream, for * example, buffers internally and blocks if you call read with $len greater * than the amount of data available, unlike recv() in C. * * Therefore, use the readAll method of the wrapped transport inside * the buffered readAll. */ public function readAll($len) { $have = strlen($this->rBuf_); if ($have == 0) { $data = $this->transport_->readAll($len); } else { if ($have < $len) { $data = $this->rBuf_; $this->rBuf_ = ''; $data .= $this->transport_->readAll($len - $have); } else { if ($have == $len) { $data = $this->rBuf_; $this->rBuf_ = ''; } else { if ($have > $len) { $data = substr($this->rBuf_, 0, $len); $this->rBuf_ = substr($this->rBuf_, $len); } } } } return $data; }
/** * Utility for skipping binary data * * @param TTransport $itrans TTransport object * @param int $type Field type */ public static function skipBinary($itrans, $type) { switch ($type) { case TType::BOOL: return $itrans->readAll(1); case TType::BYTE: return $itrans->readAll(1); case TType::I16: return $itrans->readAll(2); case TType::I32: return $itrans->readAll(4); case TType::I64: return $itrans->readAll(8); case TType::DOUBLE: return $itrans->readAll(8); case TType::STRING: $len = unpack('N', $itrans->readAll(4)); $len = $len[1]; if ($len > 0x7fffffff) { $len = 0 - ($len - 1 ^ 0xffffffff); } return 4 + $itrans->readAll($len); case TType::STRUCT: $result = 0; while (true) { $ftype = 0; $fid = 0; $data = $itrans->readAll(1); $arr = unpack('c', $data); $ftype = $arr[1]; if ($ftype == TType::STOP) { break; } // I16 field id $result += $itrans->readAll(2); $result += self::skipBinary($itrans, $ftype); } return $result; case TType::MAP: // Ktype $data = $itrans->readAll(1); $arr = unpack('c', $data); $ktype = $arr[1]; // Vtype $data = $itrans->readAll(1); $arr = unpack('c', $data); $vtype = $arr[1]; // Size $data = $itrans->readAll(4); $arr = unpack('N', $data); $size = $arr[1]; if ($size > 0x7fffffff) { $size = 0 - ($size - 1 ^ 0xffffffff); } $result = 6; for ($i = 0; $i < $size; $i++) { $result += self::skipBinary($itrans, $ktype); $result += self::skipBinary($itrans, $vtype); } return $result; case TType::SET: case TType::LST: // Vtype $data = $itrans->readAll(1); $arr = unpack('c', $data); $vtype = $arr[1]; // Size $data = $itrans->readAll(4); $arr = unpack('N', $data); $size = $arr[1]; if ($size > 0x7fffffff) { $size = 0 - ($size - 1 ^ 0xffffffff); } $result = 5; for ($i = 0; $i < $size; $i++) { $result += self::skipBinary($itrans, $vtype); } return $result; default: throw new TProtocolException('Unknown field type: ' . $type, TProtocolException::INVALID_DATA); } }