Completed
Push — master ( 633e0e...b839ec )
by thomas
35:09 queued 20:14
created

Buffertools::concat()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 3
1
<?php
2
3
namespace BitWasp\Buffertools;
4
5
class Buffertools
6
{
7
    /**
8
     * @param int $decimal
9
     * @return string
10
     * @throws \Exception
11
     */
12
    public static function numToVarIntBin($decimal)
13
    {
14
        if ($decimal < 0xfd) {
15
            $bin = chr($decimal);
16
        } elseif ($decimal <= 0xffff) {
17
            // Uint16
18
            $bin = pack("Cv", 0xfd, $decimal);
19
        } elseif ($decimal <= 0xffffffff) {
20
            // Uint32
21
            $bin = pack("CV", 0xfe, $decimal);
22
        } else {
23
            // Todo, support for 64bit integers
24
            throw new \Exception('numToVarInt(): Integer too large');
25
        }
26
27
        return $bin;
28
    }
29
30
    /**
31
     * Convert a decimal number into a VarInt Buffer
32
     *
33
     * @param  integer $decimal
34
     * @return Buffer
35
     * @throws \Exception
36
     */
37
    public static function numToVarInt($decimal)
38
    {
39
        return new Buffer(static::numToVarIntBin($decimal));
40
    }
41
42
    /**
43
     * Flip byte order of this binary string. Accepts a string or Buffer,
44
     * and will return whatever type it was given.
45
     *
46
     * @param  string|BufferInterface $bytes
47
     * @return string|BufferInterface
48
     */
49
    public static function flipBytes($bytes)
50
    {
51
        $isBuffer = $bytes instanceof BufferInterface;
52
        if ($isBuffer) {
53
            $bytes = $bytes->getBinary();
54
        }
55
56
        $flipped = implode('', array_reverse(str_split($bytes, 1)));
57
        if ($isBuffer) {
58
            $flipped = new Buffer($flipped);
59
        }
60
61
        return $flipped;
62
    }
63
64
    /**
65
     * @param BufferInterface $buffer1
66
     * @param BufferInterface $buffer2
67
     * @param int    $size
68
     * @return BufferInterface
69
     */
70
    public static function concat(BufferInterface $buffer1, BufferInterface $buffer2, $size = null)
71
    {
72
        return new Buffer($buffer1->getBinary() . $buffer2->getBinary(), $size);
73
    }
74
75
    /**
76
     *  What if we don't have two buffers, or want to guard the types of the
77
     * sorting algorithm?
78
     *
79
     * The default behaviour should be, take a list of Buffers/SerializableInterfaces, and
80
     * sort their binary representation.
81
     *
82
     * If an anonymous function is provided, we completely defer the conversion of values to
83
     * Buffer to the $convertToBuffer callable.
84
     *
85
     * This is to allow anonymous functions which are responsible for converting the item to a buffer,
86
     * and which optionally type-hint the items in the array.
87
     *
88
     * @param array $items
89
     * @param callable $convertToBuffer
90
     * @return array
91
     */
92
    public static function sort(array $items, callable $convertToBuffer = null)
93
    {
94
        if (null == $convertToBuffer) {
95
            $convertToBuffer = function ($value) {
96
                if ($value instanceof BufferInterface) {
97
                    return $value;
98
                }
99
                if ($value instanceof SerializableInterface) {
100
                    return $value->getBuffer();
101
                }
102
                throw new \RuntimeException('Requested to sort unknown type');
103
            };
104
        }
105
106
        usort($items, function ($a, $b) use ($convertToBuffer) {
107
            $av = $convertToBuffer($a)->getBinary();
108
            $bv = $convertToBuffer($b)->getBinary();
109
            return $av == $bv ? 0 : $av > $bv ? 1 : -1;
110
        });
111
112
        return $items;
113
    }
114
}
115