Completed
Push — master ( 309968...312182 )
by Harry
03:27
created

TokenStore   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 125
wmc 17
lcom 1
cbo 1
ccs 60
cts 60
cp 1
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getTokens() 0 10 2
A sort() 0 7 1
C buildTokens() 0 29 7
B setEncoding() 0 26 5
A hasChanged() 0 4 1
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 int[][] */
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 29
    public function __construct(CsvConfigurationInterface $config)
22
    {
23 29
        $this->tokens = $this->buildTokens($config);
24 29
        $this->setEncoding($config->getEncoding());
25 29
        $this->sort();
26 29
    }
27
28
    /**
29
     * @param int $mask
30
     *
31
     * @return int[]
32
     */
33 29
    public function getTokens($mask = Token::T_ANY)
34
    {
35 29
        if (!array_key_exists($mask, $this->maskStore)) {
36
            $this->maskStore[$mask] = array_filter($this->tokens, function ($type) use ($mask) {
37 29
                return $type & $mask;
38 29
            });
39 29
        }
40
41 29
        return $this->maskStore[$mask];
42
    }
43
44
    /**
45
     * @param CsvConfigurationInterface $config
46
     *
47
     * @return int[]
48
     */
49 29
    private function buildTokens(CsvConfigurationInterface $config)
50
    {
51
        $tokens = [
52 29
            $config->getDelimiter() => Token::T_DELIMITER,
53 29
        ];
54
55 29
        if ($config->getQuote() != '') {
56 27
            $tokens[$config->getQuote()] = Token::T_QUOTE;
57 27
            if ($config->useDoubleQuotes()) {
58 5
                $tokens[str_repeat($config->getQuote(), 2)] = Token::T_DOUBLE_QUOTE;
59 5
            }
60 27
        }
61 29
        if ($config->getEscape() != '') {
62 27
            $tokens[$config->getEscape()] = Token::T_ESCAPE;
63 27
        }
64
65 29
        foreach ($config->getNewLines() as $newLine) {
66 29
            $tokens[$newLine] = Token::T_NEW_LINE;
67 29
        }
68 29
        if (!is_null($config->getNullValue())) {
69 29
            $tokens[$config->getNullValue()] = Token::T_NULL;
70 29
        }
71
72 29
        foreach ($config->getBoms() as $bom) {
73 29
            $tokens[$bom] = Token::T_BOM;
74 29
        }
75
76 29
        return $tokens;
77
    }
78
79
    /**
80
     * @param string $encoding
81
     */
82 29
    public function setEncoding($encoding)
83
    {
84 29
        if ($encoding != $this->lastEncoding) {
85 29
            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 29
                    return mb_convert_encoding($string, $encoding);
92 29
                };
93
            }
94 29
            $tokens = [];
95 29
            foreach ($this->tokens as $string => $token) {
96 29
                if ($token != Token::T_BOM) {
97 29
                    $string = $changeEncoding($string);
98 29
                }
99 29
                $tokens[$string] = $token;
100 29
            }
101 29
            $this->tokens = $tokens;
102 29
            $this->sort();
103
104 29
            $this->lastEncoding = $encoding;
105 29
            $this->maskStore = [];
106 29
        }
107 29
    }
108
109
    /**
110
     * Sort the tokens into reverse key length order
111
     */
112
    private function sort()
113
    {
114
        // sort by reverse key length
115 29
        uksort($this->tokens, function ($first, $second) {
116 29
            return strlen($second) - strlen($first);
117 29
        });
118 29
    }
119
120
    /**
121
     * Determine if a mask set of tokens has changed
122
     *
123
     * @param int $mask
124
     *
125
     * @return bool
126
     */
127 26
    public function hasChanged($mask = Token::T_ANY)
128
    {
129 26
        return !isset($this->maskStore[$mask]);
130
    }
131
}
132