Project

General

Profile

1
<?php
2
/*
3
 * Licensed to the Apache Software Foundation (ASF) under one
4
 * or more contributor license agreements. See the NOTICE file
5
 * distributed with this work for additional information
6
 * regarding copyright ownership. The ASF licenses this file
7
 * to you under the Apache License, Version 2.0 (the
8
 * "License"); you may not use this file except in compliance
9
 * with the License. You may obtain a copy of the License at
10
 *
11
 *   http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing,
14
 * software distributed under the License is distributed on an
15
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
 * KIND, either express or implied. See the License for the
17
 * specific language governing permissions and limitations
18
 * under the License.
19
 *
20
 * @package thrift.transport
21
 */
22

    
23

    
24
/**
25
 * Buffered transport. Stores data to an internal buffer that it doesn't
26
 * actually write out until flush is called. For reading, we do a greedy
27
 * read and then serve data out of the internal buffer.
28
 *
29
 * @package thrift.transport
30
 */
31
class TBufferedTransport extends TTransport {
32

    
33
  /**
34
   * Constructor. Creates a buffered transport around an underlying transport
35
   */
36
  public function __construct($transport=null, $rBufSize=512, $wBufSize=512) {
37
    $this->transport_ = $transport;
38
    $this->rBufSize_ = $rBufSize;
39
    $this->wBufSize_ = $wBufSize;
40
  }
41

    
42
  /**
43
   * The underlying transport
44
   *
45
   * @var TTransport
46
   */
47
  protected $transport_ = null;
48

    
49
  /**
50
   * The receive buffer size
51
   *
52
   * @var int
53
   */
54
  protected $rBufSize_ = 512;
55

    
56
  /**
57
   * The write buffer size
58
   *
59
   * @var int
60
   */
61
  protected $wBufSize_ = 512;
62

    
63
  /**
64
   * The write buffer.
65
   *
66
   * @var string
67
   */
68
  protected $wBuf_ = '';
69

    
70
  /**
71
   * The read buffer.
72
   *
73
   * @var string
74
   */
75
  protected $rBuf_ = '';
76

    
77
  public function isOpen() {
78
    return $this->transport_->isOpen();
79
  }
80

    
81
  public function open() {
82
    $this->transport_->open();
83
  }
84

    
85
  public function close() {
86
    $this->transport_->close();
87
  }
88

    
89
  public function putBack($data) {
90
    if (strlen($this->rBuf_) === 0) {
91
      $this->rBuf_ = $data;
92
    } else {
93
      $this->rBuf_ = ($data . $this->rBuf_);
94
    }
95
  }
96

    
97
  /**
98
   * The reason that we customize readAll here is that the majority of PHP
99
   * streams are already internally buffered by PHP. The socket stream, for
100
   * example, buffers internally and blocks if you call read with $len greater
101
   * than the amount of data available, unlike recv() in C.
102
   *
103
   * Therefore, use the readAll method of the wrapped transport inside
104
   * the buffered readAll.
105
   */
106
  public function readAll($len) {
107
    $have = strlen($this->rBuf_);
108
    if ($have == 0) {
109
      $data = $this->transport_->readAll($len);
110
    } else if ($have < $len) {
111
      $data = $this->rBuf_;
112
      $this->rBuf_ = '';
113
      $data .= $this->transport_->readAll($len - $have);
114
    } else if ($have == $len) {
115
      $data = $this->rBuf_;
116
      $this->rBuf_ = '';
117
    } else if ($have > $len) {
118
      $data = substr($this->rBuf_, 0, $len);
119
      $this->rBuf_ = substr($this->rBuf_, $len);
120
    }
121
    return $data;
122
  }
123

    
124
  public function read($len) {
125
    if (strlen($this->rBuf_) === 0) {
126
      $this->rBuf_ = $this->transport_->read($this->rBufSize_);
127
    }
128

    
129
    if (strlen($this->rBuf_) <= $len) {
130
      $ret = $this->rBuf_;
131
      $this->rBuf_ = '';
132
      return $ret;
133
    }
134

    
135
    $ret = substr($this->rBuf_, 0, $len);
136
    $this->rBuf_ = substr($this->rBuf_, $len);
137
    return $ret;
138
  }
139

    
140
  public function write($buf) {
141
    $this->wBuf_ .= $buf;
142
    if (strlen($this->wBuf_) >= $this->wBufSize_) {
143
      $out = $this->wBuf_;
144

    
145
      // Note that we clear the internal wBuf_ prior to the underlying write
146
      // to ensure we're in a sane state (i.e. internal buffer cleaned)
147
      // if the underlying write throws up an exception
148
      $this->wBuf_ = '';
149
      $this->transport_->write($out);
150
    }
151
  }
152

    
153
  public function flush() {
154
    if (strlen($this->wBuf_) > 0) {
155
      $this->transport_->write($this->wBuf_);
156
      $this->wBuf_ = '';
157
    }
158
    $this->transport_->flush();
159
  }
160

    
161
}
(1-1/12)