/var/www/hkosl.com/demo_google/application/vendor/guzzlehttp/psr7/src/CachingStream.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
namespace GuzzleHttp\Psr7;

use 
Psr\Http\Message\StreamInterface;

/**
 * Stream decorator that can cache previously read bytes from a sequentially
 * read stream.
 */
class CachingStream implements StreamInterface
{
    use 
StreamDecoratorTrait;

    
/** @var StreamInterface Stream being wrapped */
    
private $remoteStream;

    
/** @var int Number of bytes to skip reading due to a write on the buffer */
    
private $skipReadBytes 0;

    
/**
     * We will treat the buffer object as the body of the stream
     *
     * @param StreamInterface $stream Stream to cache
     * @param StreamInterface $target Optionally specify where data is cached
     */
    
public function __construct(
        
StreamInterface $stream,
        
StreamInterface $target null
    
) {
        
$this->remoteStream $stream;
        
$this->stream $target ?: new Stream(fopen('php://temp''r+'));
    }

    public function 
getSize()
    {
        return 
max($this->stream->getSize(), $this->remoteStream->getSize());
    }

    public function 
rewind()
    {
        
$this->seek(0);
    }

    public function 
seek($offset$whence SEEK_SET)
    {
        if (
$whence == SEEK_SET) {
            
$byte $offset;
        } elseif (
$whence == SEEK_CUR) {
            
$byte $offset $this->tell();
        } elseif (
$whence == SEEK_END) {
            
$size $this->remoteStream->getSize();
            if (
$size === null) {
                
$size $this->cacheEntireStream();
            }
            
$byte $size $offset;
        } else {
            throw new \
InvalidArgumentException('Invalid whence');
        }

        
$diff $byte $this->stream->getSize();

        if (
$diff 0) {
            
// Read the remoteStream until we have read in at least the amount
            // of bytes requested, or we reach the end of the file.
            
while ($diff && !$this->remoteStream->eof()) {
                
$this->read($diff);
                
$diff $byte $this->stream->getSize();
            }
        } else {
            
// We can just do a normal seek since we've already seen this byte.
            
$this->stream->seek($byte);
        }
    }

    public function 
read($length)
    {
        
// Perform a regular read on any previously read data from the buffer
        
$data $this->stream->read($length);
        
$remaining $length strlen($data);

        
// More data was requested so read from the remote stream
        
if ($remaining) {
            
// If data was written to the buffer in a position that would have
            // been filled from the remote stream, then we must skip bytes on
            // the remote stream to emulate overwriting bytes from that
            // position. This mimics the behavior of other PHP stream wrappers.
            
$remoteData $this->remoteStream->read(
                
$remaining $this->skipReadBytes
            
);

            if (
$this->skipReadBytes) {
                
$len strlen($remoteData);
                
$remoteData substr($remoteData$this->skipReadBytes);
                
$this->skipReadBytes max(0$this->skipReadBytes $len);
            }

            
$data .= $remoteData;
            
$this->stream->write($remoteData);
        }

        return 
$data;
    }

    public function 
write($string)
    {
        
// When appending to the end of the currently read stream, you'll want
        // to skip bytes from being read from the remote stream to emulate
        // other stream wrappers. Basically replacing bytes of data of a fixed
        // length.
        
$overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell();
        if (
$overflow 0) {
            
$this->skipReadBytes += $overflow;
        }

        return 
$this->stream->write($string);
    }

    public function 
eof()
    {
        return 
$this->stream->eof() && $this->remoteStream->eof();
    }

    
/**
     * Close both the remote stream and buffer stream
     */
    
public function close()
    {
        
$this->remoteStream->close() && $this->stream->close();
    }

    private function 
cacheEntireStream()
    {
        
$target = new FnStream(['write' => 'strlen']);
        
copy_to_stream($this$target);

        return 
$this->tell();
    }
}