Completed
Push — master ( 12bf29...92a357 )
by Daniel
02:54
created

Stream::readInt16()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 13
Ratio 100 %

Code Coverage

Tests 9
CRAP Score 3
Metric Value
dl 13
loc 13
ccs 9
cts 9
cp 1
rs 9.4285
cc 3
eloc 7
nc 2
nop 0
crap 3
1
<?php
2
/**
3
 * This file is part of the stream package
4
 *
5
 * @author Daniel Schröder <[email protected]>
6
 */
7
8
namespace GravityMedia\Stream;
9
10
use GravityMedia\Stream\Exception;
11
12
/**
13
 * Stream
14
 *
15
 * @package GravityMedia\Stream
16
 */
17
class Stream
18
{
19
    /**
20
     * @var string[]
21
     */
22
    private static $readModes = ['r', 'w+', 'r+', 'x+', 'c+', 'rb', 'w+b', 'r+b', 'x+b', 'c+b', 'rt', 'w+t',
23
        'r+t', 'x+t', 'c+t', 'a+'];
24
25
    /**
26
     * @var string[]
27
     */
28
    private static $writeModes = ['w', 'w+', 'rw', 'r+', 'x+', 'c+', 'wb', 'w+b', 'r+b', 'x+b', 'c+b', 'w+t',
29
        'r+t', 'x+t', 'c+t', 'a', 'a+'];
30
31
    /**
32
     * @var resource
33
     */
34
    protected $resource;
35
36
    /**
37
     * @var bool
38
     */
39
    protected $local;
40
41
    /**
42
     * @var bool
43
     */
44
    protected $readable;
45
46
    /**
47
     * @var bool
48
     */
49
    protected $writable;
50
51
    /**
52
     * @var bool
53
     */
54
    protected $seekable;
55
56
    /**
57
     * @var string
58
     */
59
    protected $uri;
60
61
    /**
62
     * @var int
63
     */
64
    protected $byteOrder;
65
66
    /**
67
     * @var int
68
     */
69
    protected static $machineByteOrder;
70
71
    /**
72
     * Create stream object from resource.
73
     *
74
     * @param resource $resource
75
     *
76
     * @throws Exception\InvalidArgumentException An exception will be thrown for invalid resource arguments.
77
     *
78
     * @return static
79
     */
80 50
    public static function fromResource($resource)
81
    {
82 50
        if (!is_resource($resource)) {
83 2
            throw new Exception\InvalidArgumentException('Invalid resource');
84
        }
85
86 48
        $stream = new static();
87
88 48
        return $stream->bindResource($resource);
89
    }
90
91
    /**
92
     * Bind resource to stream and gather meta data.
93
     *
94
     * @param resource $resource The resource to bind to the stream.
95
     *
96
     * @throws Exception\InvalidArgumentException An exception will be thrown for invalid resource arguments.
97
     *
98
     * @return $this
99
     */
100 48
    public function bindResource($resource)
101
    {
102 48
        if (!is_resource($resource)) {
103 2
            throw new Exception\InvalidArgumentException('Invalid resource');
104
        }
105
106 48
        $metaData = stream_get_meta_data($resource);
107
108 48
        $this->resource = $resource;
109 48
        $this->local = stream_is_local($resource);
110 48
        $this->readable = in_array($metaData['mode'], self::$readModes);
111 48
        $this->writable = in_array($metaData['mode'], self::$writeModes);
112 48
        $this->seekable = $metaData['seekable'];
113 48
        $this->uri = $metaData['uri'];
114
115 48
        return $this;
116
    }
117
118
    /**
119
     * Return whether the stream is local.
120
     *
121
     * @return bool
122
     */
123 6
    public function isLocal()
124
    {
125 6
        return $this->local;
126
    }
127
128
    /**
129
     * Return whether read access on the stream will be granted.
130
     *
131
     * @return bool
132
     */
133 8
    public function isReadable()
134
    {
135 8
        return $this->readable;
136
    }
137
138
    /**
139
     * Return whether write access on the stream will be granted.
140
     *
141
     * @return bool
142
     */
143 12
    public function isWritable()
144
    {
145 12
        return $this->writable;
146
    }
147
148
    /**
149
     * Return whether the stream can be sought.
150
     *
151
     * @return bool
152
     */
153 12
    public function isSeekable()
154
    {
155 12
        return $this->seekable;
156
    }
157
158
    /**
159
     * Get the URI or filename associated with the stream.
160
     *
161
     * @return string
162
     */
163 4
    public function getUri()
164
    {
165 4
        return $this->uri;
166
    }
167
168
    /**
169
     * Get the byte order for integer handling.
170
     *
171
     * @return int
172
     */
173 4
    public function getByteOrder()
174
    {
175 4
        if (null === $this->byteOrder) {
176 2
            return ByteOrder::MACHINE_ENDIAN;
177
        }
178
179 2
        return $this->byteOrder;
180
    }
181
182
    /**
183
     * Set the byte order for integer handling.
184
     *
185
     * @param int $byteOrder The byte order to set. Must be one of the constants defined by the byte order enum.
186
     *
187
     * @throws Exception\InvalidArgumentException An exception will be thrown for invalid byte order arguments.
188
     *
189
     * @return $this
190
     */
191 4
    public function setByteOrder($byteOrder)
192
    {
193 4
        if (!in_array($byteOrder, ByteOrder::values(), true)) {
194 2
            throw new Exception\InvalidArgumentException('Invalid byte order');
195
        }
196
197 2
        $this->byteOrder = $byteOrder;
198
199 2
        return $this;
200
    }
201
202
    /**
203
     * Get the machine byte order.
204
     *
205
     * @return int
206
     */
207 156
    public function getMachineByteOrder()
208
    {
209 156
        if (null === static::$machineByteOrder) {
210 2
            static::$machineByteOrder = ByteOrder::BIG_ENDIAN;
211
212 2
            list(, $value) = unpack('s', "\x01\x00");
213 2
            if (1 === $value) {
214 2
                static::$machineByteOrder = ByteOrder::LITTLE_ENDIAN;
215 1
            }
216 1
        }
217
218 156
        return static::$machineByteOrder;
219
    }
220
221
    /**
222
     * Get information about the stream.
223
     *
224
     * @param string $info The information to retrieve.
225
     *
226
     * @throws Exception\IOException An exception will be thrown for invalid stream resources.
227
     *
228
     * @return int
229
     */
230 4
    protected function getStat($info)
231
    {
232 4
        if (!is_resource($this->resource)) {
233 2
            throw new Exception\IOException('Invalid stream resource');
234
        }
235
236 2
        $uri = $this->getUri();
237 2
        if (is_string($uri)) {
238 2
            clearstatcache(true, $uri);
239 1
        }
240
241 2
        $stat = fstat($this->resource);
242
243 2
        return $stat[$info];
244
    }
245
246
    /**
247
     * Get size of the stream in bytes
248
     *
249
     * @throws Exception\BadMethodCallException An exception will be thrown for non-local streams.
250
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources.
251
     *
252
     * @return int
253
     */
254 6
    public function getSize()
255
    {
256 6
        if (!$this->isLocal()) {
257 2
            throw new Exception\BadMethodCallException('Stream not local');
258
        }
259
260 4
        return $this->getStat('size');
261
    }
262
263
    /**
264
     * Return whether the end of the stream was reached.
265
     *
266
     * @throws Exception\IOException An exception will be thrown for invalid stream resources.
267
     *
268
     * @return bool
269
     * @link   http://www.php.net/manual/en/function.feof.php
270
     */
271 4
    public function eof()
272
    {
273 4
        if (!is_resource($this->resource)) {
274 2
            throw new Exception\IOException('Invalid stream resource');
275
        }
276
277 2
        return feof($this->resource);
278
    }
279
280
    /**
281
     * Return the current position of the stream.
282
     *
283
     * @throws Exception\IOException An exception will be thrown for invalid stream resources.
284
     *
285
     * @return int
286
     * @link   http://www.php.net/manual/en/function.ftell.php
287
     */
288 8
    public function tell()
289
    {
290 8
        if (!is_resource($this->resource)) {
291 2
            throw new Exception\IOException('Invalid stream resource');
292
        }
293
294 6
        return ftell($this->resource);
295
    }
296
297
    /**
298
     * Seek and return the position of the stream.
299
     *
300
     * @param int $offset The offset.
301
     * @param int $whence Either SEEK_SET (which is default), SEEK_CUR or SEEK_END.
302
     *
303
     * @throws Exception\BadMethodCallException An exception will be thrown for non-seekable streams.
304
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
305
     *                                          position could not be set.
306
     *
307
     * @return int
308
     * @link   http://www.php.net/manual/en/function.fseek.php
309
     */
310 12
    public function seek($offset, $whence = SEEK_SET)
311
    {
312 12
        if (!$this->isSeekable()) {
313 2
            throw new Exception\BadMethodCallException('Stream not seekable');
314
        }
315
316 10
        if (!is_resource($this->resource)) {
317 2
            throw new Exception\IOException('Invalid stream resource');
318
        }
319
320 8
        if (fseek($this->resource, $offset, $whence) < 0) {
321 2
            throw new Exception\IOException('Unexpected result of operation');
322
        }
323
324 6
        return $this->tell();
325
    }
326
327
    /**
328
     * Rewind the position of the stream.
329
     *
330
     * @throws Exception\BadMethodCallException An exception will be thrown for non-seekable streams.
331
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
332
     *                                          position could not be set.
333
     *
334
     * @return int
335
     */
336 2
    public function rewind()
337
    {
338 2
        return $this->seek(0);
339
    }
340
341
    /**
342
     * Read up to $length number of bytes of data from the stream.
343
     *
344
     * @param int $length The maximum number of bytes to read.
345
     *
346
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
347
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
348
     *                                          data could not be read.
349
     *
350
     * @return string
351
     * @link   http://www.php.net/manual/en/function.fread.php
352
     */
353 8 View Code Duplication
    public function read($length)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
354
    {
355 8
        if (!$this->isReadable()) {
356 2
            throw new Exception\BadMethodCallException('Stream not readable');
357
        }
358
359 6
        if (!is_resource($this->resource)) {
360 2
            throw new Exception\IOException('Invalid stream resource');
361
        }
362
363 4
        $data = @fread($this->resource, $length);
364 4
        if (false === $data) {
365 2
            throw new Exception\IOException('Unexpected result of operation');
366
        }
367
368 2
        return $data;
369
    }
370
371
    /**
372
     * Read signed 8-bit integer (char) data from the stream.
373
     *
374
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
375
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
376
     *                                          data could not be read.
377
     *
378
     * @return int
379
     */
380 6
    public function readInt8()
381
    {
382 6
        list(, $value) = unpack('c', $this->read(1));
383 6
        return $value;
384
    }
385
386
    /**
387
     * Read unsigned 8-bit integer (char) data from the stream.
388
     *
389
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
390
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
391
     *                                          data could not be read.
392
     *
393
     * @return int
394
     */
395 8
    public function readUInt8()
396
    {
397 8
        list(, $value) = unpack('C', $this->read(1));
398 8
        return $value;
399
    }
400
401
    /**
402
     * Read signed 16-bit integer (short) data from the stream.
403
     *
404
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
405
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
406
     *                                          data could not be read.
407
     *
408
     * @return int
409
     */
410 18 View Code Duplication
    public function readInt16()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
411
    {
412 18
        $data = $this->read(2);
413
414 18
        if ($this->getByteOrder() !== ByteOrder::MACHINE_ENDIAN
415 18
            && $this->getByteOrder() !== $this->getMachineByteOrder()
416 9
        ) {
417 6
            $data = strrev($data);
418 3
        }
419
420 18
        list(, $value) = unpack('s', $data);
421 18
        return $value;
422
    }
423
424
    /**
425
     * Read unsigned 16-bit integer (short) data from the stream.
426
     *
427
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
428
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
429
     *                                          data could not be read.
430
     *
431
     * @return int
432
     */
433 30 View Code Duplication
    public function readUInt16()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
434
    {
435 30
        switch ($this->getByteOrder()) {
436 30
            case ByteOrder::BIG_ENDIAN:
437 10
                $format = 'n';
438 10
                break;
439 20
            case ByteOrder::LITTLE_ENDIAN:
440 10
                $format = 'v';
441 10
                break;
442 5
            default:
443 10
                $format = 'S';
444 15
        }
445
446 30
        list(, $value) = unpack($format, $this->read(2));
447 30
        return $value;
448
    }
449
450
    /**
451
     * Read signed 24-bit integer (short) data from the stream.
452
     *
453
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
454
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
455
     *                                          data could not be read.
456
     *
457
     * @return int
458
     */
459 18
    public function readInt24()
460
    {
461 18
        $value = $this->readUInt24();
462
463 18
        if ($value & 0x800000) {
464 6
            return $value - 2 ** 24;
465
        }
466
467 12
        return $value;
468
    }
469
470
    /**
471
     * Read unsigned 24-bit integer (short) data from the stream.
472
     *
473
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
474
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
475
     *                                          data could not be read.
476
     *
477
     * @return int
478
     */
479 42
    public function readUInt24()
480
    {
481 42
        $data = $this->read(3);
482
483 42
        $byteOrder = $this->getByteOrder();
484 42
        if ($byteOrder === ByteOrder::MACHINE_ENDIAN) {
485 14
            $byteOrder = $this->getMachineByteOrder();
486 7
        }
487
488 42
        if ($byteOrder !== $this->getMachineByteOrder()) {
489 14
            $data = strrev($data);
490 7
        }
491
492 42
        $values = unpack('C3', $data);
493 42
        return $values[1] | $values[2] << 8 | $values[3] << 16;
494
    }
495
496
    /**
497
     * Read signed 32-bit integer (long) data from the stream.
498
     *
499
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
500
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
501
     *                                          data could not be read.
502
     *
503
     * @return int
504
     */
505 18 View Code Duplication
    public function readInt32()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
506
    {
507 18
        $data = $this->read(4);
508
509 18
        if ($this->getByteOrder() !== ByteOrder::MACHINE_ENDIAN
510 18
            && $this->getByteOrder() !== $this->getMachineByteOrder()
511 9
        ) {
512 6
            $data = strrev($data);
513 3
        }
514
515 18
        list(, $value) = unpack('l', $data);
516 18
        return $value;
517
    }
518
519
    /**
520
     * Read unsigned 32-bit integer (long) data from the stream.
521
     *
522
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
523
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
524
     *                                          data could not be read.
525
     *
526
     * @return int
527
     */
528 24 View Code Duplication
    public function readUInt32()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
529
    {
530 24
        switch ($this->getByteOrder()) {
531 24
            case ByteOrder::BIG_ENDIAN:
532 8
                $format = 'N';
533 8
                break;
534 16
            case ByteOrder::LITTLE_ENDIAN:
535 8
                $format = 'V';
536 8
                break;
537 4
            default:
538 8
                $format = 'L';
539 12
        }
540
541 24
        list(, $value) = unpack($format, $this->read(4));
542 24
        return $value;
543
    }
544
545
    /**
546
     * Read signed 64-bit integer (long long) data from the stream.
547
     *
548
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
549
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
550
     *                                          data could not be read.
551
     *
552
     * @return int
553
     */
554 18 View Code Duplication
    public function readInt64()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
555
    {
556 18
        $data = $this->read(8);
557
558 18
        if ($this->getByteOrder() !== ByteOrder::MACHINE_ENDIAN
559 18
            && $this->getByteOrder() !== $this->getMachineByteOrder()
560 9
        ) {
561 6
            $data = strrev($data);
562 3
        }
563
564 18
        list(, $value) = unpack('q', $data);
565 18
        return $value;
566
    }
567
568
    /**
569
     * Read unsigned 64-bit integer (long long) data from the stream.
570
     *
571
     * @throws Exception\BadMethodCallException An exception will be thrown for non-readable streams.
572
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
573
     *                                          data could not be read.
574
     *
575
     * @return int
576
     */
577 24 View Code Duplication
    public function readUInt64()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
578
    {
579 24
        switch ($this->getByteOrder()) {
580 24
            case ByteOrder::BIG_ENDIAN:
581 8
                $format = 'J';
582 8
                break;
583 16
            case ByteOrder::LITTLE_ENDIAN:
584 8
                $format = 'P';
585 8
                break;
586 4
            default:
587 8
                $format = 'Q';
588 12
        }
589
590 24
        list(, $value) = unpack($format, $this->read(8));
591 24
        return $value;
592
    }
593
594
    /**
595
     * Write data to the stream and return the number of bytes written.
596
     *
597
     * @param string $data The data
598
     *
599
     * @throws Exception\BadMethodCallException An exception will be thrown for non-writable streams.
600
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
601
     *                                          data could not be written.
602
     *
603
     * @return int
604
     * @link   http://www.php.net/manual/en/function.fwrite.php
605
     */
606 8 View Code Duplication
    public function write($data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
607
    {
608 8
        if (!$this->isWritable()) {
609 2
            throw new Exception\BadMethodCallException('Stream not writable');
610
        }
611
612 6
        if (!is_resource($this->resource)) {
613 2
            throw new Exception\IOException('Invalid stream resource');
614
        }
615
616 4
        $length = @fwrite($this->resource, $data);
617 4
        if (false === $length) {
618 2
            throw new Exception\IOException('Unexpected result of operation');
619
        }
620
621 2
        return $length;
622
    }
623
624
    /**
625
     * Write signed 8-bit integer (char) data to the stream
626
     *
627
     * @param int $value The value
628
     *
629
     * @return int
630
     */
631 6
    public function writeInt8($value)
632
    {
633 6
        return $this->write(pack('c', $value));
634
    }
635
636
    /**
637
     * Write unsigned 8-bit integer (char) data to the stream
638
     *
639
     * @param int $value The value
640
     *
641
     * @return int
642
     */
643 8
    public function writeUInt8($value)
644
    {
645 8
        return $this->write(pack('C', $value));
646
    }
647
648
    /**
649
     * Write signed 16-bit integer (short) data to the stream
650
     *
651
     * @param int $value The value
652
     *
653
     * @return int
654
     */
655 18
    public function writeInt16($value)
656
    {
657 18
        $data = pack('s', $value);
658
659 18
        if ($this->getByteOrder() !== ByteOrder::MACHINE_ENDIAN
660 18
            && $this->getByteOrder() !== $this->getMachineByteOrder()
661 9
        ) {
662 6
            $data = strrev($data);
663 3
        }
664
665 18
        return $this->write($data);
666
    }
667
668
    /**
669
     * Write unsigned 16-bit integer (short) data to the stream
670
     *
671
     * @param int $value The value
672
     *
673
     * @return int
674
     */
675 30
    public function writeUInt16($value)
676
    {
677 30
        switch ($this->getByteOrder()) {
678 30
            case ByteOrder::BIG_ENDIAN:
679 10
                $format = 'n';
680 10
                break;
681 20
            case ByteOrder::LITTLE_ENDIAN:
682 10
                $format = 'v';
683 10
                break;
684 5
            default:
685 10
                $format = 'S';
686 15
        }
687
688 30
        return $this->write(pack($format, $value));
689
    }
690
691
    /**
692
     * Write signed 24-bit integer (short) data to the stream
693
     *
694
     * @param int $value The value
695
     *
696
     * @return int
697
     */
698 18
    public function writeInt24($value)
699
    {
700 18
        if ($value & 0x7fffff) {
701 6
            $value += 2 ** 24;
702 3
        }
703
704 18
        return $this->writeUInt24($value);
705
    }
706
707
    /**
708
     * Write unsigned 24-bit integer (short) data to the stream
709
     *
710
     * @param int $value The value
711
     *
712
     * @return int
713
     */
714 42
    public function writeUInt24($value)
715
    {
716 42
        $data = pack('C3', $value, $value >> 8, $value >> 16);
717
718 42
        $byteOrder = $this->getByteOrder();
719 42
        if ($byteOrder === ByteOrder::MACHINE_ENDIAN) {
720 14
            $byteOrder = $this->getMachineByteOrder();
721 7
        }
722
723 42
        if ($byteOrder !== $this->getMachineByteOrder()) {
724 14
            $data = strrev($data);
725 7
        }
726
727 42
        return $this->write($data);
728
    }
729
730
    /**
731
     * Write signed 32-bit integer (long) data to the stream
732
     *
733
     * @param int $value The value
734
     *
735
     * @return int
736
     */
737 18
    public function writeInt32($value)
738
    {
739 18
        $data = pack('l', $value);
740
741 18
        if ($this->getByteOrder() !== ByteOrder::MACHINE_ENDIAN
742 18
            && $this->getByteOrder() !== $this->getMachineByteOrder()
743 9
        ) {
744 6
            $data = strrev($data);
745 3
        }
746
747 18
        return $this->write($data);
748
    }
749
750
    /**
751
     * Write unsigned 32-bit integer (long) data to the stream
752
     *
753
     * @param int $value The value
754
     *
755
     * @return int
756
     */
757 24
    public function writeUInt32($value)
758
    {
759 24
        switch ($this->getByteOrder()) {
760 24
            case ByteOrder::BIG_ENDIAN:
761 8
                $format = 'N';
762 8
                break;
763 16
            case ByteOrder::LITTLE_ENDIAN:
764 8
                $format = 'V';
765 8
                break;
766 4
            default:
767 8
                $format = 'L';
768 12
        }
769
770 24
        return $this->write(pack($format, $value));
771
    }
772
773
    /**
774
     * Write signed 64-bit integer (long long) data to the stream
775
     *
776
     * @param int $value The value
777
     *
778
     * @return int
779
     */
780 18
    public function writeInt64($value)
781
    {
782 18
        $data = pack('q', $value);
783
784 18
        if ($this->getByteOrder() !== ByteOrder::MACHINE_ENDIAN
785 18
            && $this->getByteOrder() !== $this->getMachineByteOrder()
786 9
        ) {
787 6
            $data = strrev($data);
788 3
        }
789
790 18
        return $this->write($data);
791
    }
792
793
    /**
794
     * Write unsigned 64-bit integer (long long) data to the stream
795
     *
796
     * @param int $value The value
797
     *
798
     * @return int
799
     */
800 24
    public function writeUInt64($value)
801
    {
802 24
        switch ($this->getByteOrder()) {
803 24
            case ByteOrder::BIG_ENDIAN:
804 8
                $format = 'J';
805 8
                break;
806 16
            case ByteOrder::LITTLE_ENDIAN:
807 8
                $format = 'P';
808 8
                break;
809 4
            default:
810 8
                $format = 'Q';
811 12
        }
812
813 24
        return $this->write(pack($format, $value));
814
    }
815
816
    /**
817
     * Truncate the stream to a given length.
818
     *
819
     * @param int $size The size to truncate to.
820
     *
821
     * @throws Exception\BadMethodCallException An exception will be thrown for non-writable streams.
822
     * @throws Exception\IOException            An exception will be thrown for invalid stream resources or when the
823
     *                                          stream could not be truncated.
824
     *
825
     * @return bool
826
     * @link   http://www.php.net/manual/en/function.ftruncate.php
827
     */
828 6
    public function truncate($size)
829
    {
830 6
        if (!$this->isWritable()) {
831 2
            throw new Exception\BadMethodCallException('Stream not writable');
832
        }
833
834 4
        if (!is_resource($this->resource)) {
835 2
            throw new Exception\IOException('Invalid stream resource');
836
        }
837
838 2
        return @ftruncate($this->resource, $size);
839
    }
840
841
    /**
842
     * Close the stream.
843
     *
844
     * @return bool
845
     * @link   http://www.php.net/manual/en/function.fclose.php
846
     */
847 16
    public function close()
848
    {
849 16
        return @fclose($this->resource);
850
    }
851
}
852