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
 * Framed transport. Writes and reads data in chunks that are stamped with
26
 * their length.
27
 *
28
 * @package thrift.transport
29
 */
30
class TFramedTransport extends TTransport {
31

    
32
  /**
33
   * Underlying transport object.
34
   *
35
   * @var TTransport
36
   */
37
  private $transport_;
38

    
39
  /**
40
   * Buffer for read data.
41
   *
42
   * @var string
43
   */
44
  private $rBuf_;
45

    
46
  /**
47
   * Buffer for queued output data
48
   *
49
   * @var string
50
   */
51
  private $wBuf_;
52

    
53
  /**
54
   * Whether to frame reads
55
   *
56
   * @var bool
57
   */
58
  private $read_;
59

    
60
  /**
61
   * Whether to frame writes
62
   *
63
   * @var bool
64
   */
65
  private $write_;
66

    
67
  /**
68
   * Constructor.
69
   *
70
   * @param TTransport $transport Underlying transport
71
   */
72
  public function __construct($transport=null, $read=true, $write=true) {
73
    $this->transport_ = $transport;
74
    $this->read_ = $read;
75
    $this->write_ = $write;
76
  }
77

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

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

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

    
90
  /**
91
   * Reads from the buffer. When more data is required reads another entire
92
   * chunk and serves future reads out of that.
93
   *
94
   * @param int $len How much data
95
   */
96
  public function read($len) {
97
    if (!$this->read_) {
98
      return $this->transport_->read($len);
99
    }
100

    
101
    if (strlen($this->rBuf_) === 0) {
102
      $this->readFrame();
103
    }
104

    
105
    // Just return full buff
106
    if ($len >= strlen($this->rBuf_)) {
107
      $out = $this->rBuf_;
108
      $this->rBuf_ = null;
109
      return $out;
110
    }
111

    
112
    // Return substr
113
    $out = substr($this->rBuf_, 0, $len);
114
    $this->rBuf_ = substr($this->rBuf_, $len);
115
    return $out;
116
  }
117

    
118
  /**
119
   * Put previously read data back into the buffer
120
   *
121
   * @param string $data data to return
122
   */
123
  public function putBack($data) {
124
    if (strlen($this->rBuf_) === 0) {
125
      $this->rBuf_ = $data;
126
    } else {
127
      $this->rBuf_ = ($data . $this->rBuf_);
128
    }
129
  }
130

    
131
  /**
132
   * Reads a chunk of data into the internal read buffer.
133
   */
134
  private function readFrame() {
135
    $buf = $this->transport_->readAll(4);
136
    $val = unpack('N', $buf);
137
    $sz = $val[1];
138

    
139
    $this->rBuf_ = $this->transport_->readAll($sz);
140
  }
141

    
142
  /**
143
   * Writes some data to the pending output buffer.
144
   *
145
   * @param string $buf The data
146
   * @param int    $len Limit of bytes to write
147
   */
148
  public function write($buf, $len=null) {
149
    if (!$this->write_) {
150
      return $this->transport_->write($buf, $len);
151
    }
152

    
153
    if ($len !== null && $len < strlen($buf)) {
154
      $buf = substr($buf, 0, $len);
155
    }
156
    $this->wBuf_ .= $buf;
157
  }
158

    
159
  /**
160
   * Writes the output buffer to the stream in the format of a 4-byte length
161
   * followed by the actual data.
162
   */
163
  public function flush() {
164
    if (!$this->write_ || strlen($this->wBuf_) == 0) {
165
      return $this->transport_->flush();
166
    }
167

    
168
    $out = pack('N', strlen($this->wBuf_));
169
    $out .= $this->wBuf_;
170

    
171
    // Note that we clear the internal wBuf_ prior to the underlying write
172
    // to ensure we're in a sane state (i.e. internal buffer cleaned)
173
    // if the underlying write throws up an exception
174
    $this->wBuf_ = '';
175
    $this->transport_->write($out);
176
    $this->transport_->flush();
177
  }
178

    
179
}
(2-2/12)