Buffertools::numToVarInt()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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