Passed
Push — master ( 927f67...9bd000 )
by Claudson
06:56
created

Layout   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Test Coverage

Coverage 95%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
eloc 40
dl 0
loc 109
ccs 38
cts 40
cp 0.95
rs 10
c 1
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A append() 0 10 3
A getContents() 0 3 1
A getTotalOfRecords() 0 3 1
A getStructure() 0 3 1
A parse() 0 43 5
A makeFileObject() 0 8 1
1
<?php
2
3
namespace Claudsonm\Pedi\Structure;
4
5
use Claudsonm\Pedi\Exceptions\PediException;
6
use SplTempFileObject;
7
8
class Layout
9
{
10
    /**
11
     * @var array|Record[]
12
     */
13
    protected array $contents = [];
14
15
    /**
16
     * Defines the records and their occurrences within the layout.
17
     */
18
    protected array $structure = [];
19
20
    private SplTempFileObject $file;
21
22
    /**
23
     * Adds a record definition to the end of the layout structure.
24
     *
25
     * @param int|string $occurrences the amount of sequential items expected for the given record
26
     *
27
     * @throws PediException
28
     *
29
     * @return $this
30
     */
31 57
    public function append(Record $record, $occurrences = 1): self
32
    {
33 57
        if (! preg_match('/^([1-9][0-9]*)|(\*)$/', $occurrences)) {
34 5
            throw PediException::invalidQuantifier();
35
        }
36
37 52
        $occurrences = '*' === $occurrences ? $occurrences : (int) $occurrences;
38 52
        $this->structure[] = [$record, $occurrences];
39
40 52
        return $this;
41
    }
42
43 4
    public function getStructure(): array
44
    {
45 4
        return $this->structure;
46
    }
47
48
    /**
49
     * @return array|Record[]
50
     */
51 48
    public function getContents(): array
52
    {
53 48
        return $this->contents;
54
    }
55
56 48
    public function getTotalOfRecords(): int
57
    {
58 48
        return count($this->contents);
59
    }
60
61 48
    public function parse(string $fileContent)
62
    {
63 48
        $this->file = $this->makeFileObject($fileContent);
64 48
        $currentSection = 0;
65 48
        while ($this->file->valid()) {
66
            // $line = $this->file->getCurrentLine();
67
            // $endOfCurrentLine = $this->file->ftell();
68
            // ----------
69
            /** @var Record $baseRecord */
70 48
            [$baseRecord, $times] = $this->structure[$currentSection];
71
72
            do {
73 48
                $line = $this->file->getCurrentLine();
74 48
                $endOfCurrentLine = $this->file->ftell();
75
76
                /** @var Record $item */
77 48
                $item = unserialize(serialize($baseRecord));
78 48
                $item->setLineNumber($this->file->key() + 1);
79 48
                $item->parse($line);
80 48
                $this->contents[] = $item;
81
82 48
                if ('*' === $times) {
83
                    try {
84 44
                        $nextLine = $this->file->getCurrentLine();
85
                    } catch (\RuntimeException $exception) {
86
                        break;
87
                    }
88 44
                    $this->file->fseek($endOfCurrentLine);
89 44
                    $moreRecordsExists = $baseRecord->matches($nextLine);
90
                } else {
91 48
                    $times--;
92 48
                    $moreRecordsExists = $times > 0;
93
                }
94 48
            } while ($moreRecordsExists);
95
96
            // -----------
97
            /*try {
98
                $nextLine = $this->file->getCurrentLine();
99
            } catch (\RuntimeException $exception) {
100
                break;
101
            }*/
102
            // -----------
103 48
            $currentSection++;
104
            /*
105
            $this->file->fseek($endOfCurrentLine);*/
106
        }
107 48
    }
108
109 48
    private function makeFileObject(string $fileContent): SplTempFileObject
110
    {
111 48
        $file = new SplTempFileObject();
112 48
        $file->setFlags(SplTempFileObject::DROP_NEW_LINE);
113 48
        $file->fwrite($fileContent);
114 48
        $file->rewind();
115
116 48
        return $file;
117
    }
118
}
119