Completed
Pull Request — master (#7)
by Harry
02:53
created

TokenStore::setEncoding()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 5

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 26
ccs 21
cts 21
cp 1
rs 8.439
cc 5
eloc 17
nc 7
nop 1
crap 5
1
<?php
2
3
namespace Graze\CsvToken\Tokeniser\Token;
4
5
use Graze\CsvToken\Csv\CsvConfigurationInterface;
6
7
class TokenStore implements TokenStoreInterface
8
{
9
    /** @var array[] */
10
    private $maskStore = [];
11
    /** @var int[] */
12
    private $tokens = [];
13
    /** @var string|null */
14
    private $lastEncoding = null;
15
16
    /**
17
     * TokenStore constructor.
18
     *
19
     * @param CsvConfigurationInterface $config
20
     */
21 28
    public function __construct(CsvConfigurationInterface $config)
22
    {
23 28
        $this->tokens = $this->buildTokens($config);
24 28
        $this->setEncoding($config->getEncoding());
25 28
        $this->sort();
26 28
    }
27
28
    /**
29
     * @param int $mask
30
     *
31
     * @return array
32
     */
33 28
    public function getTokens($mask = Token::T_ANY)
34
    {
35 28
        if (!array_key_exists($mask, $this->maskStore)) {
36
            $this->maskStore[$mask] = array_filter($this->tokens, function ($type) use ($mask) {
37 28
                return $type & $mask;
38 28
            });
39 28
        }
40
41 28
        return $this->maskStore[$mask];
42
    }
43
44
    /**
45
     * @param CsvConfigurationInterface $config
46
     *
47
     * @return int[]
48
     */
49 28
    private function buildTokens(CsvConfigurationInterface $config)
50
    {
51
        $tokens = [
52 28
            $config->getDelimiter() => Token::T_DELIMITER,
53 28
        ];
54
55 28
        if ($config->getQuote() != '') {
56 26
            $tokens[$config->getQuote()] = Token::T_QUOTE;
57 26
            if ($config->useDoubleQuotes()) {
58 4
                $tokens[str_repeat($config->getQuote(), 2)] = Token::T_DOUBLE_QUOTE;
59 4
            }
60 26
        }
61 28
        if ($config->getEscape() != '') {
62 26
            $tokens[$config->getEscape()] = Token::T_ESCAPE;
63 26
        }
64
65 28
        foreach ($config->getNewLines() as $newLine) {
66 28
            $tokens[$newLine] = Token::T_NEW_LINE;
67 28
        }
68 28
        if (!is_null($config->getNullValue())) {
69 28
            $tokens[$config->getNullValue()] = Token::T_NULL;
70 28
        }
71
72 28
        foreach ($config->getBoms() as $bom) {
73 28
            $tokens[$bom] = Token::T_BOM;
74 28
        }
75
76 28
        return $tokens;
77
    }
78
79
    /**
80
     * @param string $encoding
81
     */
82 28
    public function setEncoding($encoding)
83
    {
84 28
        if ($encoding != $this->lastEncoding) {
85 28
            if (!is_null($this->lastEncoding)) {
86
                $changeEncoding = function ($string) use ($encoding) {
87 2
                    return mb_convert_encoding($string, $encoding, $this->lastEncoding);
88 2
                };
89 2
            } else {
90
                $changeEncoding = function ($string) use ($encoding) {
91 28
                    return mb_convert_encoding($string, $encoding);
92 28
                };
93
            }
94 28
            $tokens = [];
95 28
            foreach ($this->tokens as $string => $token) {
96 28
                if ($token != Token::T_BOM) {
97 28
                    $string = $changeEncoding($string);
98 28
                }
99 28
                $tokens[$string] = $token;
100 28
            }
101 28
            $this->tokens = $tokens;
102 28
            $this->sort();
103
104 28
            $this->lastEncoding = $encoding;
105 28
            $this->maskStore = [];
106 28
        }
107 28
    }
108
109
    /**
110
     * Sort the tokens into reverse key length order
111
     */
112
    private function sort()
113
    {
114
        // sort by reverse key length
115 28
        uksort($this->tokens, function ($first, $second) {
116 28
            return strlen($second) - strlen($first);
117 28
        });
118 28
    }
119
}
120