Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
3
namespace Guzzle\Http;
4
 
5
/**
6
 * EntityBody decorator used to return only a subset of an entity body
7
 */
8
class ReadLimitEntityBody extends AbstractEntityBodyDecorator
9
{
10
    /** @var int Limit the number of bytes that can be read */
11
    protected $limit;
12
 
13
    /** @var int Offset to start reading from */
14
    protected $offset;
15
 
16
    /**
17
     * @param EntityBodyInterface $body   Body to wrap
18
     * @param int                 $limit  Total number of bytes to allow to be read from the stream
19
     * @param int                 $offset Position to seek to before reading (only works on seekable streams)
20
     */
21
    public function __construct(EntityBodyInterface $body, $limit, $offset = 0)
22
    {
23
        parent::__construct($body);
24
        $this->setLimit($limit)->setOffset($offset);
25
    }
26
 
27
    /**
28
     * Returns only a subset of the decorated entity body when cast as a string
29
     * {@inheritdoc}
30
     */
31
    public function __toString()
32
    {
33
        return substr((string) $this->body, $this->offset, $this->limit) ?: '';
34
    }
35
 
36
    public function isConsumed()
37
    {
38
        return $this->body->isConsumed() ||
39
            ($this->body->ftell() >= $this->offset + $this->limit);
40
    }
41
 
42
    /**
43
     * Returns the Content-Length of the limited subset of data
44
     * {@inheritdoc}
45
     */
46
    public function getContentLength()
47
    {
48
        $length = $this->body->getContentLength();
49
 
50
        return $length === false
51
            ? $this->limit
52
            : min($this->limit, min($length, $this->offset + $this->limit) - $this->offset);
53
    }
54
 
55
    /**
56
     * Allow for a bounded seek on the read limited entity body
57
     * {@inheritdoc}
58
     */
59
    public function seek($offset, $whence = SEEK_SET)
60
    {
61
        return $whence === SEEK_SET
62
            ? $this->body->seek(max($this->offset, min($this->offset + $this->limit, $offset)))
63
            : false;
64
    }
65
 
66
    /**
67
     * Set the offset to start limiting from
68
     *
69
     * @param int $offset Offset to seek to and begin byte limiting from
70
     *
71
     * @return self
72
     */
73
    public function setOffset($offset)
74
    {
75
        $this->body->seek($offset);
76
        $this->offset = $offset;
77
 
78
        return $this;
79
    }
80
 
81
    /**
82
     * Set the limit of bytes that the decorator allows to be read from the stream
83
     *
84
     * @param int $limit Total number of bytes to allow to be read from the stream
85
     *
86
     * @return self
87
     */
88
    public function setLimit($limit)
89
    {
90
        $this->limit = $limit;
91
 
92
        return $this;
93
    }
94
 
95
    public function read($length)
96
    {
97
        // Check if the current position is less than the total allowed bytes + original offset
98
        $remaining = ($this->offset + $this->limit) - $this->body->ftell();
99
        if ($remaining > 0) {
100
            // Only return the amount of requested data, ensuring that the byte limit is not exceeded
101
            return $this->body->read(min($remaining, $length));
102
        } else {
103
            return false;
104
        }
105
    }
106
}