forked from rawilk/laravel-printing
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAttributeGroup.php
90 lines (75 loc) · 2.57 KB
/
AttributeGroup.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<?php
declare(strict_types=1);
namespace Rawilk\Printing\Api\Cups;
use Rawilk\Printing\Api\Cups\Exceptions\TypeNotSpecified;
abstract class AttributeGroup
{
/**
* Every attribute group has a specific delimiter tag
*
* @see https://www.rfc-editor.org/rfc/rfc2910#section-3.5
*/
protected int $tag;
/**
* @var array<string, \Rawilk\Printing\Api\Cups\Type|array<int, \Rawilk\Printing\Api\Cups\Type>>
*/
protected array $attributes = [];
public function __set($name, $value)
{
$this->attributes[$name] = $value;
}
public function __construct(array $attributes = [])
{
$this->attributes = $attributes;
}
/**
* @var array<string, \Rawilk\Printing\Api\Cups\Type|array<int, \Rawilk\Printing\Api\Cups\Type>>
*/
public function getAttributes()
{
return $this->attributes;
}
public function encode(): string
{
$binary = pack('c', $this->tag);
foreach ($this->attributes as $name => $value) {
if (gettype($value) === 'array') {
$binary .= $this->handleArrayEncode($name, $value);
continue;
}
if (!$value instanceof Type) {
throw new TypeNotSpecified('Attribute value has to be of type ' . Type::class);
}
$nameLen = strlen($name);
$binary .= pack('c', $value->getTag());
$binary .= pack('n', $nameLen); // Attribute key length
$binary .= pack('a' . $nameLen, $name); // Attribute key
$binary .= $value->encode(); // Attribute value (with length)
}
return $binary;
}
/**
* If attribute is an array, the attribute name after the first element is empty
* @param string $name
* @param array<int, \Rawilk\Printing\Api\Cups\Type> $values
*/
private function handleArrayEncode(string $name, array $values): string
{
$str = '';
if ($values[0] instanceof \Rawilk\Printing\Api\Cups\Types\RangeOfInteger) {
\Rawilk\Printing\Api\Cups\Types\RangeOfInteger::checkOverlaps($values);
}
for ($i = 0; $i < sizeof($values); $i++) {
$_name = $name;
if ($i !== 0) {
$_name = '';
}
$nameLen = strlen($_name);
$str .= pack('c', $values[$i]->getTag()); // Value tag
$str .= pack('n', $nameLen); // Attribute key length
$str .= pack('a' . $nameLen, $_name); // Attribute key
$str .= $values[$i]->encode();
}
return $str;
}
}