Completed
Pull Request — master (#7)
by Harry
06:13 queued 03:25
created

TokenStore::buildTokens()   D

Complexity

Conditions 9
Paths 192

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 38
ccs 30
cts 30
cp 1
rs 4.6666
cc 9
eloc 23
nc 192
nop 1
crap 9
1
<?php
2
3
namespace Graze\CsvToken\Tokeniser\Token;
4
5
use Graze\CsvToken\Csv\Bom;
6
use Graze\CsvToken\Csv\CsvConfigurationInterface;
7
8
class TokenStore implements TokenStoreInterface
9
{
10
    /** @var array[] */
11
    private $maskStore = [];
12
    /** @var int[] */
13
    private $tokens = [];
14
    /** @var string|null */
15
    private $lastEncoding = null;
16
17
    /**
18
     * TokenStore constructor.
19
     *
20
     * @param CsvConfigurationInterface $config
21
     */
22 28
    public function __construct(CsvConfigurationInterface $config)
23
    {
24 28
        $this->tokens = $this->buildTokens($config);
25 28
        $this->setEncoding($config->getEncoding());
26 28
        $this->sort();
27 28
    }
28
29
    /**
30
     * @param int $mask
31
     *
32
     * @return array
33
     */
34 28
    public function getTokens($mask = Token::T_ANY)
35
    {
36 28
        if (!array_key_exists($mask, $this->maskStore)) {
37
            $this->maskStore[$mask] = array_filter($this->tokens, function ($type) use ($mask) {
38 28
                return $type & $mask;
39 28
            });
40 28
        }
41
42 28
        return $this->maskStore[$mask];
43
    }
44
45
    /**
46
     * @param CsvConfigurationInterface $config
47
     *
48
     * @return int[]
49
     */
50 28
    private function buildTokens(CsvConfigurationInterface $config)
51
    {
52
        $tokens = [
53 28
            $config->getDelimiter() => Token::T_DELIMITER,
54 28
        ];
55
56 28
        if ($config->getQuote() != '') {
57 26
            $tokens[$config->getQuote()] = Token::T_QUOTE;
58 26
            if ($config->useDoubleQuotes()) {
59 4
                $tokens[str_repeat($config->getQuote(), 2)] = Token::T_DOUBLE_QUOTE;
60 4
            }
61 26
        }
62 28
        if ($config->getEscape() != '') {
63 26
            $tokens[$config->getEscape()] = Token::T_ESCAPE;
64 26
        }
65
66 28
        $newLines = $config->getNewLine();
67 28
        if (!is_array($newLines)) {
68 28
            $newLines = [$newLines];
69 28
        }
70 28
        foreach ($newLines as $newLine) {
71 28
            $tokens[$newLine] = Token::T_NEW_LINE;
72 28
        }
73 28
        if (!is_null($config->getNullValue())) {
74 28
            $tokens[$config->getNullValue()] = Token::T_NULL;
75 28
        }
76
77 28
        if (is_null($config->getBom())) {
78 27
            $boms = [Bom::BOM_UTF8, Bom::BOM_UTF16_BE, Bom::BOM_UTF16_LE, Bom::BOM_UTF32_BE, Bom::BOM_UTF32_LE];
79 27
        } else {
80 1
            $boms = [$config->getBom()];
81
        }
82 28
        foreach ($boms as $bom) {
83 28
            $tokens[$bom] = Token::T_BOM;
84 28
        }
85
86 28
        return $tokens;
87
    }
88
89
    /**
90
     * @param string $encoding
91
     */
92 28
    public function setEncoding($encoding)
93
    {
94 28
        if ($encoding != $this->lastEncoding) {
95 28
            if ($this->lastEncoding) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->lastEncoding of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
96
                $changeEncoding = function ($string) use ($encoding) {
97 2
                    return mb_convert_encoding($string, $encoding, $this->lastEncoding);
98 2
                };
99 2
            } else {
100
                $changeEncoding = function ($string) use ($encoding) {
101 28
                    return mb_convert_encoding($string, $encoding);
102 28
                };
103
            }
104 28
            $tokens = [];
105 28
            foreach ($this->tokens as $string => $token) {
106 28
                if ($token != Token::T_BOM) {
107 28
                    $string = $changeEncoding($string);
108 28
                }
109 28
                $tokens[$string] = $token;
110 28
            }
111 28
            $this->tokens = $tokens;
112 28
            $this->sort();
113
114 28
            $this->lastEncoding = $encoding;
115 28
            $this->maskStore = [];
116 28
        }
117 28
    }
118
119
    /**
120
     * Sort the tokens into reverse key length order
121
     */
122
    private function sort()
123
    {
124
        // sort by reverse key length
125 28
        uksort($this->tokens, function ($first, $second) {
126 28
            return strlen($second) - strlen($first);
127 28
        });
128 28
    }
129
}
130