Completed
Branch refactor/142 (8a1d2c)
by Luke
02:46
created

Resource::getContextParams()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * CSVelte: Slender, elegant CSV for PHP.
4
 *
5
 * Inspired by Python's CSV module and Frictionless Data and the W3C's CSV
6
 * standardization efforts, CSVelte was written in an effort to take all the
7
 * suck out of working with CSV.
8
 *
9
 * @version   v0.2.1
10
 * @copyright Copyright (c) 2016 Luke Visinoni <[email protected]>
11
 * @author    Luke Visinoni <[email protected]>
12
 * @license   https://github.com/deni-zen/csvelte/blob/master/LICENSE The MIT License (MIT)
13
 */
14
namespace CSVelte\IO;
15
16
use \InvalidArgumentException;
17
use CSVelte\Exception\IOException;
18
19
/**
20
 * Stream Resource.
21
 *
22
 * Represents a stream resource connection. May be open or closed. This allows
23
 * me to provide a nice, clean, easy-to-use interface for opening stream
24
 * resources in a particular mode as well as to lazy-open a stream.
25
 *
26
 * @package    CSVelte
27
 * @subpackage CSVelte\IO
28
 * @copyright  (c) 2016, Luke Visinoni <[email protected]>
29
 * @author     Luke Visinoni <[email protected]>
30
 * @since      v0.2.1
31
 */
32
class Resource
33
{
34
    /**
35
     * Available base access modes
36
     * @var string base access mode must be one of these letters
37
     */
38
    protected static $bases = "rwaxc";
39
40
    /**
41
     * Hash of readable/writable stream open mode types.
42
     *
43
     * Mercilessly stolen from:
44
     * https://github.com/guzzle/streams/blob/master/src/Stream.php
45
     *
46
     * My kudos and sincere thanks go out to Michael Dowling and Graham Campbell
47
     * of the guzzle/streams PHP package. Thanks for the inspiration (in some cases)
48
     * and the not suing me for outright theft (in this case).
49
     *
50
     * @var array Hash of readable and writable stream types
51
     * @todo I think I can get rid of this by simply checking whether base is a
52
     *     particular letter OR plus is present... try it
53
     * @todo Why are x and c (alone) not even on either of these lists?
54
     *       I just figured out why... readable and writable default to false. So
55
     *       only modes that change that default behavior are listed here
56
     */
57
    protected static $readWriteHash = [
58
        'read' => [
59
            'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
60
            'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
61
            'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
62
            'x+t' => true, 'c+t' => true, 'a+' => true,
63
        ],
64
        'write' => [
65
            'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
66
            'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
67
            'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
68
            'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true,
69
        ],
70
    ];
71
72
    /**
73
     * Stream URI.
74
     *
75
     * Contains the stream URI to connect to.
76
     *
77
     * @var string The stream uri
78
     */
79
    protected $uri;
80
81
    /**
82
     * Stream resource handle.
83
     *
84
     * Contains the underlying stream resource handle (if there is one).
85
     * Otherwise it will be null.
86
     *
87
     * @var resource The stream resource handle
88
     */
89
    protected $conn;
90
91
    /**
92
     * Lazy open switch.
93
     *
94
     * Determines whether the actual fopen for this resource should be delayed
95
     * until an I/O operation is performed.
96
     *
97
     * @var boolean True if connection is lazy
98
     */
99
    protected $lazy;
100
101
    /**
102
     * Extra context to open the resource with.
103
     *
104
     * An associative array of context options and parameters.
105
     *
106
     * @var array An associative array of stream context options and params
107
     * @see http://php.net/manual/en/stream.contexts.php
108
     */
109
    protected $context = [
110
        'options' => [],
111
        'params' => []
112
    ];
113
114
    /**
115
     * Context resource handle.
116
     *
117
     * Holds a context resource handle object for $this->context
118
     *
119
     * @var resource The context resource handle
120
     */
121
    protected $crh;
122
123
    /**
124
     * Should fopen use include path?
125
     *
126
     * @var boolean True if fopen should use the include path to find potential files
127
     */
128
    protected $useIncludePath;
129
130
    /**
131
     * Base open mode.
132
     *
133
     * @var string A single character for base open mode (r, w, a, x or c)
134
     */
135
    protected $base = '';
136
137
    /**
138
     * Plus reading or plus writing.
139
     *
140
     * @var string Either a plus or an empty string
141
     */
142
    protected $plus = '';
143
144
    /**
145
     * Binary or text flag.
146
     *
147
     * @var string Either "b" or "t" for binary or text
148
     */
149
    protected $flag = '';
150
151
    /**
152
     * Does access mode string indicate readability?
153
     *
154
     * @var bool Whether access mode indicates readability
155
     */
156
    protected $readable = false;
157
158
    /**
159
     * Does access mode string indicate writability
160
     *
161
     * @var bool Whether access mode indicates writability
162
     */
163
    protected $writable = false;
164
165
    /**
166
     * Resource constructor.
167
     *
168
     * Instantiates a stream resource. If lazy is set to true, the connection
169
     * is delayed until the first call to getResource().
170
     *
171
     * @param string|resource $uri  The URI to connect to OR a stream resource handle
172
     * @param string $mode The connection mode
173
     * @param boolean $lazy Whether connection should be deferred until an I/O
174
     *     operation is requested (such as read or write) on the attached stream
175
     * @throws \CSVelte\Exception\IOException if connection fails
176
     * @todo Does stream_get_meta_data belong in Stream or Resource?
177
     */
178 96
    public function __construct($uri, $mode = null, $lazy = null, $use_include_path = null, $context_options = null, $context_params = null)
179
    {
180
        // first, check if we're wrapping an existing stream resource
181 96
        if (is_resource($handle = $uri)) {
182 5
            if (($resource_type = get_resource_type($handle)) != ($exp_resource_type = "stream")) {
183
                throw new InvalidArgumentException(sprintf(
184
                    'Invalid stream resource type for %s, expected "%s", got: "%s"',
185
                    __METHOD__,
186
                    $exp_resource_type,
187
                    $resource_type
188
                ));
189
            }
190
            // set all this manually
191 5
            $meta = stream_get_meta_data($handle);
192 5
            $this->setUri($meta['uri'])
193 5
                 ->setMode($meta['mode']);
194 5
            $this->conn = $handle;
195 5
            return;
196
        }
197
198
        // ok we're opening a new stream resource handle
199 91
        $this->setUri($uri)
1 ignored issue
show
Bug introduced by
It seems like $uri defined by parameter $uri on line 178 can also be of type resource; however, CSVelte\IO\Resource::setUri() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
200 90
             ->setMode($mode)
201 90
             ->setLazy($lazy)
202 90
             ->setUseIncludePath($use_include_path)
203 90
             ->setContext($context_options, $context_params);
204 90
        if (!$this->isLazy()) {
205 3
            $this->connect();
206 2
        }
207 89
    }
208
209
    /**
210
     * Class destructor
211
     */
212 91
    public function __destruct()
213
    {
214 91
        $this->disconnect();
215 91
    }
216
217
    /**
218
     * Invoke magic method.
219
     *
220
     * Creates and returns a Stream object for this resource
221
     *
222
     * @return resource The underlying stream resource
223
     */
224 3
    public function __invoke()
225
    {
226 3
        return new Stream($this);
227
    }
228
229
    /**
230
     * Connect (open connection) to file/stream.
231
     *
232
     * File open is (by default) delayed until the user explicitly calls connect()
233
     * or they request the resource handle with getHandle().
234
     *
235
     * @return boolean True if connection was successful
236
     * @throws \CSVelte\Exception\IOException if connection fails
237
     */
238 81
    public function connect()
239
    {
240 81
        if (!$this->isConnected()) {
241 81
            $e = null;
242 81
            $errhandler = function ($errno, $errstr, $errfile, $errline) use (&$e) {
0 ignored issues
show
Unused Code introduced by
The parameter $errno is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $errstr is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $errfile is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $errline is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
243 4
                $e = new IOException(sprintf(
244 4
                    "Could not open connection for %s using mode %s.",
245 4
                    $this->getUri(),
246 4
                    $this->getMode()
247 4
                ), IOException::ERR_STREAM_CONNECTION_FAILED);
248 81
            };
249 81
            set_error_handler($errhandler->bindTo($this));
250 81
            $this->conn = fopen(
251 81
                $this->getUri(),
252 81
                $this->getMode(),
253 81
                $this->getUseIncludePath(),
254 81
                $this->getContext()
255 81
            );
256 81
            restore_error_handler();
257 81
            if ($e) throw $e;
258 77
        }
259 77
        return $this->isConnected();
260
    }
261
262
    /**
263
     * Close connection.
264
     *
265
     * Close the connection to this stream (if open).
266
     *
267
     * @return boolean|null Whether close was successful, or null if already closed
268
     */
269 91
    public function disconnect()
270
    {
271 91
        if ($this->isConnected()) {
272 82
            return fclose($this->conn);
273
        }
274
        // return null if nothing to close
275 80
        return;
0 ignored issues
show
Coding Style introduced by
Empty return statement not required here
Loading history...
276
    }
277
278
    /**
279
     * Set stream URI.
280
     *
281
     * Set the stream URI. Can only be set if the connection isn't open yet.
282
     * If you try to set the URI on an open resource, an IOException will be thrown
283
     *
284
     * @param string $uri The URI for this stream resource to open
285
     * @return $this
286
     * @throws \InvalidArgumentException if not a valid stream uri
287
     * @throws \CSVelte\Exception\IOException if stream has already been opened
288
     * @todo I'm pretty sure that the parse_url function is too restrictive. It
289
     *     will reject URIs that are perfectly valid.
290
     */
291 96
    public function setUri($uri)
292
    {
293 96
        $this->assertNotConnected(__METHOD__);
294
295 96
        if (is_object($uri) && method_exists($uri, '__toString')) {
296
            $uri = (string) $uri;
297
        }
298
299 96
        if (is_string($uri) && parse_url($uri)) {
300 95
            $this->uri = $uri;
301 95
            return $this;
302
        }
303
304 1
        throw new InvalidArgumentException(sprintf(
305 1
            'Not a valid stream uri, expected "%s", got: "%s"',
306 1
            'string',
307 1
            gettype($uri)
308 1
        ));
309
    }
310
311
    /**
312
     * Set the fopen mode.
313
     *
314
     * Thank you to GitHub user "binsoul" whose AccessMode class inspired this
315
     * Also thanks to the author(s) of Guzzle streams implementation, where the
316
     * readwritehash idea came from. Both libraries are MIT licensed, so my
317
     * merciless theft of their code is alright.
318
     *
319
     * @param string $mode A 1-3 character string determining open mode
320
     * @return $this
321
     * @throws \InvalidArgumentException if not a valid stream access mode
322
     * @throws \CSVelte\Exception\IOException if stream has already been opened
323
     * @see http://php.net/manual/en/function.fopen.php
324
     * @see https://github.com/binsoul/io-stream/blob/master/src/AccessMode.php
325
     * @see https://raw.githubusercontent.com/guzzle/streams/master/src/Stream.php
326
     * @todo convert $mode to lower case and test it
327
     */
328 95
    public function setMode($mode = null)
329
    {
330 95
        $this->assertNotConnected(__METHOD__);
331 95
        if (is_null($mode)) $mode = "r+b";
332
333 95
        $mode = substr($mode, 0, 3);
334 95
        $rest = substr($mode, 1);
335
336 95
        $base = substr($mode, 0, 1);
337 95
        $plus = (strpos($rest, '+') !== false) ? '+' : '';
338 95
        $flag = trim($rest, '+');
339
340 95
        $this->flag = '';
341 95
        $this->setBaseMode($base)
342 95
             ->setIsPlus($plus == '+')
343 95
             ->setIsText($flag == 't')
344 95
             ->setIsBinary($flag == 'b');
345
346 95
        return $this;
347
    }
348
349
    /**
350
     * Update access parameters.
351
     *
352
     * After changing any of the access mode parameters, this method must be
353
     * called in order for readable and writable to stay accurate.
354
     *
355
     * @return $this
356
     */
357 95
    protected function updateAccess()
358
    {
359 95
        $this->readable = isset(self::$readWriteHash['read'][$this->getMode()]);
360 95
        $this->writable = isset(self::$readWriteHash['write'][$this->getMode()]);
361 95
        return $this;
362
    }
363
364
    /**
365
     * Set base access mode character.
366
     *
367
     * @param string $base The base mode character (must be one of "rwaxc")
368
     * @return $this
369
     * @throws \InvalidArgumentException If passed invalid base char
370
     * @throws \CSVelte\Exception\IOException if stream has already been opened
371
     */
372 95
    public function setBaseMode($base)
373
    {
374 95
        $this->assertNotConnected(__METHOD__);
375 95
        if (strpos(self::$bases, $base) === false) {
376
            throw new InvalidArgumentException("\"{$base}\" is not a valid base stream access mode.");
377
        }
378 95
        $this->base = $base;
379 95
        return $this->updateAccess();
380
    }
381
382
    /**
383
     * Set plus mode.
384
     *
385
     * @param boolean $isPlus Whether base access mode should include the + sign
386
     * @return $this
387
     * @throws \CSVelte\Exception\IOException if stream has already been opened
388
     */
389 95
    public function setIsPlus($isPlus)
390
    {
391 95
        $this->assertNotConnected(__METHOD__);
392 95
        $this->plus = $isPlus ? '+' : '';
393 95
        return $this->updateAccess();
394
    }
395
396
    /**
397
     * Set binary-safe mode.
398
     *
399
     * @param boolean $isBinary Whether binary safe mode or not
400
     * @return $this
401
     * @throws \CSVelte\Exception\IOException if stream has already been opened
402
     */
403 95
    public function setIsBinary($isBinary)
404
    {
405 95
        $this->assertNotConnected(__METHOD__);
406 95
        if ($isBinary) {
407 67
            $this->flag = 'b';
408 67
        }
409 95
        return $this;
410
    }
411
412
    /**
413
     * Set text mode.
414
     *
415
     * @param boolean $isText Whether text mode or not
416
     * @return $this
417
     * @throws \CSVelte\Exception\IOException if stream has already been opened
418
     */
419 95
    public function setIsText($isText)
420
    {
421 95
        $this->assertNotConnected(__METHOD__);
422 95
        if ($isText) {
423 1
            $this->flag = 't';
424 1
        }
425 95
        return $this;
426
    }
427
428
    /**
429
     * Set lazy flag.
430
     *
431
     * Set the lazy flag, which tells the class whether to defer the connection
432
     * until the user specifically requests it.
433
     *
434
     * @param boolean|null Whether or not to "lazily" open the stream
435
     * @return $this
436
     */
437 90
    protected function setLazy($lazy)
438
    {
439 90
        if (is_null($lazy)) $lazy = true;
440 90
        $this->lazy = (boolean) $lazy;
441 90
        return $this;
442
    }
443
444
    /**
445
     * Set use include path flag.
446
     *
447
     * Sets whether or not fopen should search the include path for files. Can
448
     * only be set if resource isn't open already. If called when resource is
449
     * already open an exception will be thrown.
450
     *
451
     * @param boolean $use_include_path Whether to search include path for files
452
     * @throws \CSVelte\Exception\IOException
453
     * @return $this
454
     */
455 90
    public function setUseIncludePath($use_include_path)
456
    {
457 90
        $this->assertNotConnected(__METHOD__);
458 90
        $this->useIncludePath = (boolean) $use_include_path;
459 90
        return $this;
460
    }
461
462
    /**
463
     * Set stream context options and params.
464
     *
465
     * Sets arrays of stream context options and params. Check out the URI below
466
     * for more on stream contexts.
467
     *
468
     * @param array|null $options Stream context options
469
     * @param array|null $params  Stream Context params
470
     * @return $this
471
     * @see http://php.net/manual/en/stream.contexts.php
472
     */
473 90
    public function setContext($options = null, $params = null)
474
    {
475 90
        if (is_array($options)) {
476 2
            foreach ($options as $wrap => $opts) {
477 2
                $this->setContextOptions($opts, $wrap);
478 2
            }
479 2
        }
480 90
        if (!is_null($params)) {
481 2
            $this->setContextParams($params);
482 2
        }
483 90
        return $this;
484
    }
485
486
    /**
487
     * Set context resource directly
488
     * @param resource|null $context Stream context resource to set directly
489
     * @return $this
490
     * @see http://php.net/manual/en/function.stream-context-create.php
491
     * @todo Need to write a unit test for passing this method a null value
492
     */
493 77
    public function setContextResource($context)
494
    {
495 77
        if (!is_null($context)) {
496 8
            if (!is_resource($context) || get_resource_type($context) != "stream-context") {
497 4
                throw new InvalidArgumentException(sprintf(
498 4
                    "Invalid argument for %s. Expecting resource of type \"stream-context\" but got: \"%s\"",
499 4
                    __METHOD__,
500 4
                    gettype($context)
501 4
                ));
502
            }
503
            // don't need to call updateContext() because its already a context resource
504 4
            $this->crh = $context;
505 4
        }
506 73
        return $this;
507
    }
508
509
    /**
510
     * Update the stream context.
511
     *
512
     * After setting/updating stream context options and/or params, this method
513
     * must be called in order to update the stream context resource.
514
     *
515
     * @return $this
516
     */
517 2
    protected function updateContext()
518
    {
519
        // if already connected, set the options on the context resource
520
        // otherwise, it will be set at connection time
521 2
        if ($this->isConnected()) {
522
            // set options and params on existing stream resource
523 1
            stream_context_set_params(
524 1
                $this->getContext(),
525 1
                $this->getContextParams() + [
526 1
                    'options' => $this->getContextOptions()
527 1
                ]
528 1
            );
529 1
        }
530 2
        return $this;
531
    }
532
533
    /**
534
     * Set context options.
535
     *
536
     * Sets stream context options for this stream resource.
537
     *
538
     * @param array $options An array of stream context options
539
     * @param string $wrapper The wrapper these options belong to (if no wrapper
540
     *     argument, then $options should be an associative array with key being
541
     *     a wrapper name and value being its options)
542
     * @return $this
543
     * @throws \InvalidArgumentException if passed invalid options or wrapper
544
     * @see http://php.net/manual/en/stream.contexts.php
545
     */
546 2
    public function setContextOptions($options, $wrapper = null)
547
    {
548 2
        if (is_array($options)) {
549 2
            if (is_null($wrapper)) {
550
                $this->context['options'] = $options;
551
            } else {
552 2
                $this->assertValidWrapper($wrapper);
553 2
                $this->context['options'][$wrapper] = $options;
554
            }
555 2
            $this->updateContext();
556 2
            return $this;
557
        }
558
        throw new InvalidArgumentException("Context options must be an array, got: " . gettype($options));
559
    }
560
561
    /**
562
     * Set context params.
563
     *
564
     * Set the context params for this stream resource.
565
     *
566
     * @param array $params An array of stream resource params
567
     * @return $this
568
     * @throws \InvalidArgumentException if passed invalid params
569
     * @see http://php.net/manual/en/stream.contexts.php
570
     */
571 2
    public function setContextParams($params)
572
    {
573 2
        if (is_array($params)) {
574 2
            $this->context['params'] = $params;
575 2
            $this->updateContext();
576 2
            return $this;
577
        }
578
        throw new InvalidArgumentException("Context parameters must be an array, got: " . gettype($params));
579
    }
580
581
    /**
582
     * Get context options for this stream resource.
583
     *
584
     * Returns the stream context options for this stream resource. Either all
585
     * options for all wrappers, or just the options for the specified wrapper.
586
     *
587
     * @param  string $wrapper If present, return options only for this wrapper
588
     * @return array Context options (either all or for specified wrapper)
589
     * @throws \InvalidArgumentException if the wrapper doesn't exist
590
     */
591 81
    public function getContextOptions($wrapper = null)
592
    {
593 81
        if (is_null($wrapper)) {
594 81
            return $this->context['options'];
595
        }
596
        $this->assertValidWrapper($wrapper);
597
        if (isset($this->context['options'][$wrapper])) {
598
            return $this->context['options'][$wrapper];
599
        }
600
    }
601
602
    /**
603
     * Get context params for this stream resource.
604
     *
605
     * Returns the stream context params for this stream resource.
606
     *
607
     * @return array Context params for this stream resource
608
     */
609 81
    public function getContextParams()
610
    {
611 81
        return $this->context['params'];
612
    }
613
614
    /**
615
     * Get stream context resource.
616
     * @return resource|null The stream context resource
617
     */
618 84
    public function getContext()
619
    {
620
        // if context resource hasn't been created, create one
621 84
        if (is_null($this->crh)) {
622 81
            $this->crh = stream_context_create(
623 81
                $this->getContextOptions(),
624 81
                $this->getContextParams()
625 81
            );
626 81
        }
627
        // return context resource handle
628 84
        return $this->crh;
629
    }
630
631
    /**
632
     * Retrieve underlying stream resource handle.
633
     *
634
     * An accessor method for the underlying stream resource object. Also triggers
635
     * stream connection if in lazy open mode. Because this method may potentially
636
     * call the connect() method, it is possible that it may throw an exception
637
     * if there is some issue with opening the stream.
638
     *
639
     * @return resource The underlying stream resource handle
640
     * @throws \CSVelte\Exception\IOException
641
     */
642 67
    public function getHandle()
643
    {
644 67
        if (!$this->isConnected() && $this->isLazy()) {
645 5
            $this->connect();
646 4
        }
647 66
        return $this->conn;
648
    }
649
650
    /**
651
     * Is the stream connection open?
652
     *
653
     * Tells you whether this stream resource is open or not.
654
     *
655
     * @return boolean Whether the stream is open
656
     */
657 96
    public function isConnected()
658
    {
659 96
        return is_resource($this->conn);
660
    }
661
662
    /**
663
     * Get the stream URI.
664
     *
665
     * Accessor method for stream URI.
666
     *
667
     * @return string The stream URI
668
     */
669 81
    public function getUri()
670
    {
671 81
        return $this->uri;
672
    }
673
674
    /**
675
     * Get the access mode.
676
     *
677
     * Tells you what the access mode is. This is the short string of characters
678
     * that you would pass to the fopen function to tell it how to open a file/stream
679
     *
680
     * @return string The file/stream access mode
681
     * @see http://php.net/manual/en/function.fopen.php
682
     */
683 95
    public function getMode()
684
    {
685 95
        return sprintf(
686 95
            "%s%s%s",
687 95
            $this->base,
688 95
            $this->plus,
689 95
            $this->flag
690 95
        );
691
    }
692
693
    /**
694
     * Is access mode binary-safe?
695
     * @return boolean Whether binary-safe flag is set
696
     */
697 4
    public function isBinary()
698
    {
699 4
        return $this->flag == "b";
700
    }
701
702
    /**
703
     * Is stream connected in text mode?
704
     * @return boolean Whether text mode flag is set
705
     */
706 3
    public function isText()
707
    {
708 3
        return $this->flag == "t";
709
    }
710
711
    /**
712
     * Is this a lazy open resource?
713
     * @return boolean Whether this is a lazily-opened resource
714
     */
715 90
    public function isLazy()
716
    {
717 90
        return $this->lazy;
718
    }
719
720
    /**
721
     * Should fopen search include path?
722
     * @return boolean Whether fopen should search include path for files
723
     */
724 81
    public function getUseIncludePath()
725
    {
726 81
        return $this->useIncludePath;
727
    }
728
729
    /**
730
     * Does the access mode string indicate readability?
731
     *
732
     * Readable, in this context, only refers to the manner in which this stream
733
     * resource was opened (if it even is opened yet). It is no indicator about
734
     * whether or not the underlying stream actually supports read operations.
735
     * It simply refers to the access mode string passed to it by the user.
736
     *
737
     * @return boolean Whether access mode indicates readability
738
     */
739 52
    public function isReadable()
740
    {
741 52
        return $this->readable;
742
    }
743
744
    /**
745
     * Does the access mode string indicate writability?
746
     *
747
     * Writable, in this context, only refers to the manner in which this stream
748
     * resource was opened (if it even is opened yet). It is no indicator about
749
     * whether or not the underlying stream actually supports write operations.
750
     * It simply refers to the access mode string passed to it by the user.
751
     *
752
     * @return boolean Whether access mode indicates writability
753
     */
754 21
    public function isWritable()
755
    {
756 21
        return $this->writable;
757
    }
758
759
    /**
760
     * Is cursor positioned at the beginning of stream?
761
     *
762
     * Returns true if this stream resource's access mode positions the internal
763
     * cursor at the beginning of the stream.
764
     *
765
     * @return boolean Whether cursor positioned at beginning of stream
766
     */
767 2
    public function isCursorPositionedAtBeginning()
768
    {
769 2
        return $this->base != 'a';
770
    }
771
772
    /**
773
     * Is cursor positioned at the end of stream?
774
     *
775
     * Returns true if this stream resource's access mode positions the internal
776
     * cursor at the end of the stream.
777
     *
778
     * @return boolean Whether cursor positioned at end of stream
779
     */
780 2
    public function isCursorPositionedAtEnd()
781
    {
782 2
        return $this->base == 'a';
783
    }
784
785
    /**
786
     * Is content truncated to zero-length on opening?
787
     *
788
     * Returns true if this stream resource's access mode indicates truncation of
789
     * stream content to zero-length upon opening.
790
     *
791
     * @return boolean Whether stream content is truncated on opening
792
     */
793 3
    public function isTruncated()
794
    {
795 3
        return $this->base == 'w';
796
    }
797
798
    /**
799
     * Does stream access mode indicate file creation?
800
     *
801
     * Returns true if this stream's access mode implies that PHP will attempt to
802
     * create a file if none exists.
803
     *
804
     * @return boolean Whether PHP should attempt to create file at $uri
805
     */
806 1
    public function attemptsFileCreation()
807
    {
808 1
        return $this->base != 'r';
809
    }
810
811
    /**
812
     * Does stream access mode indicate the rejection of existing files?
813
     *
814
     * Returns true if this stream's access mode implies that PHP will fail to
815
     * open a file if it already exists.
816
     *
817
     * @return boolean Whether PHP should attempt to create file at $uri
818
     */
819 1
    public function rejectsExistingFiles()
820
    {
821 1
        return $this->base == 'x';
822
    }
823
824
    /**
825
     * Are write operations appended to the end of the stream?
826
     *
827
     * Returns true if write operations are appended to the end of the stream
828
     * regardless of the position of the read cursor.
829
     *
830
     * @return boolean Whether write operations ore always appended
831
     */
832 1
    public function appendsWriteOps()
833
    {
834 1
        return $this->base == 'w';
835
    }
836
837
    /**
838
     * Assert that stream resource is not open.
839
     *
840
     * Used internally to ensure that stream is not open, since some methods should
841
     * only be called on unopened stream resources.
842
     *
843
     * @param  string The method that is asserting
844
     * @return void
845
     * @throws \CSVelte\Exception\IOException if stream is open
846
     */
847 96
    protected function assertNotConnected($method)
848
    {
849 96
        if ($this->isConnected()) {
850
            throw new IOException("Cannot perform this operation on a stream once it has already been opened: {$method}", IOException::ERR_STREAM_ALREADY_OPEN);
851
        }
852 96
    }
853
854
    /**
855
     * Assert that given wrapper is a valid, registered stream wrapper
856
     *
857
     * Used internally to ensure that a given stream wrapper is valid and available
858
     *
859
     * @param  string The name of the stream wrapper
860
     * @return void
861
     * @throws \InvalidArgumentException if wrapper doesn't exist
862
     */
863 2
    protected function assertValidWrapper($name)
864
    {
865 2
        if (!in_array($name, stream_get_wrappers())) {
866
            throw new InvalidArgumentException("{$name} is not a known stream wrapper.");
867
        }
868 2
    }
869
870
}
871