EcSerializer   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Test Coverage

Coverage 55.88%

Importance

Changes 0
Metric Value
eloc 47
dl 0
loc 127
ccs 19
cts 34
cp 0.5588
rs 10
c 0
b 0
f 0
wmc 14

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getAdapterImplPath() 0 9 2
A disableCache() 0 4 1
A getImplRelPath() 0 21 5
A getSerializer() 0 19 5
A getImplPaths() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Bitcoin\Crypto\EcAdapter;
6
7
use BitWasp\Bitcoin\Bitcoin;
8
use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface;
9
use BitWasp\Bitcoin\Crypto\EcAdapter\Serializer\Key\PrivateKeySerializerInterface;
10
use BitWasp\Bitcoin\Crypto\EcAdapter\Serializer\Key\PublicKeySerializerInterface;
11
use BitWasp\Bitcoin\Crypto\EcAdapter\Serializer\Signature\CompactSignatureSerializerInterface;
12
use BitWasp\Bitcoin\Crypto\EcAdapter\Serializer\Signature\DerSignatureSerializerInterface;
13
14
class EcSerializer
15
{
16
    const PATH_PHPECC = 'BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\\';
17
    const PATH_SECP256K1 = 'BitWasp\Bitcoin\Crypto\EcAdapter\Impl\Secp256k1\\';
18
19
    /**
20
     * @var string[]
21
     */
22
    private static $serializerInterface = [
23
        PrivateKeySerializerInterface::class,
24
        PublicKeySerializerInterface::class,
25
        CompactSignatureSerializerInterface::class,
26
        DerSignatureSerializerInterface::class,
27
    ];
28
29
    /**
30
     * @var string[]
31
     */
32
    private static $serializerImpl = [
33
        'Serializer\Key\PrivateKeySerializer',
34
        'Serializer\Key\PublicKeySerializer',
35
        'Serializer\Signature\CompactSignatureSerializer',
36
        'Serializer\Signature\DerSignatureSerializer'
37
    ];
38
39
    /**
40
     * @var array
41
     */
42
    private static $map = [];
43
44
    /**
45
     * @var bool
46
     */
47
    private static $useCache = true;
48
49
    /**
50
     * @var array
51
     */
52
    private static $cache = [];
53
54
    /**
55
     * @param string $interface
56
     * @return string
57
     */
58 5117
    public static function getImplRelPath(string $interface): string
59
    {
60 5117
        if (0 === count(self::$map)) {
61
            if (!in_array($interface, self::$serializerInterface, true)) {
62
                throw new \InvalidArgumentException('Interface not known');
63
            }
64
65
            $cInterface = count(self::$serializerInterface);
66
            if ($cInterface !== count(self::$serializerImpl)) {
67
                throw new \InvalidArgumentException('Invalid serializer interface map');
68
            }
69
70
            for ($i = 0; $i < $cInterface; $i++) {
71
                /** @var string $iface */
72
                $iface = self::$serializerInterface[$i];
73
                $ipath = self::$serializerImpl[$i];
74
                self::$map[$iface] = $ipath;
75
            }
76
        }
77
78 5117
        return self::$map[$interface];
79
    }
80
81
    /**
82
     * @return array
83
     */
84 5117
    public static function getImplPaths(): array
85
    {
86
        return [
87 5117
            'BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Adapter\EcAdapter' => 'BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\\',
88
            'BitWasp\Bitcoin\Crypto\EcAdapter\Impl\Secp256k1\Adapter\EcAdapter' => 'BitWasp\Bitcoin\Crypto\EcAdapter\Impl\Secp256k1\\'
89
        ];
90
    }
91
92
    /**
93
     * @param EcAdapterInterface $adapter
94
     * @return string
95
     */
96 5117
    public static function getAdapterImplPath(EcAdapterInterface $adapter): string
97
    {
98 5117
        $paths = static::getImplPaths();
99 5117
        $class = get_class($adapter);
100 5117
        if (!isset($paths[$class])) {
101
            throw new \RuntimeException('Unknown EcAdapter');
102
        }
103
104 5117
        return $paths[$class];
105
    }
106
107
    /**
108
     * @param string $interface
109
     * @param bool $useCache
110
     * @param EcAdapterInterface $adapter
111
     * @return mixed
112
     */
113 5117
    public static function getSerializer(string $interface, $useCache = true, EcAdapterInterface $adapter = null)
114
    {
115 5117
        if (null === $adapter) {
116 121
            $adapter = Bitcoin::getEcAdapter();
117
        }
118
119 5117
        $key = get_class($adapter) . ":" . $interface;
120 5117
        if (array_key_exists($key, self::$cache)) {
121
            return self::$cache[$key];
122
        }
123
124 5117
        $classPath = self::getAdapterImplPath($adapter) . self::getImplRelPath($interface);
125 5117
        $class = new $classPath($adapter);
126
127 5117
        if ($useCache && self::$useCache) {
128
            self::$cache[$key] = $class;
129
        }
130
131 5117
        return $class;
132
    }
133
134
    /**
135
     * Disables caching of serializers
136
     */
137
    public static function disableCache()
138
    {
139
        self::$useCache = false;
140
        self::$cache = [];
141
    }
142
}
143