1<?php 2declare(strict_types = 1); 3 4namespace BaconQrCode\Common; 5 6use BaconQrCode\Exception\InvalidArgumentException; 7use DASPRiD\Enum\AbstractEnum; 8 9/** 10 * Encapsulates a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1 of ISO 18004. 11 * 12 * @method static self CP437() 13 * @method static self ISO8859_1() 14 * @method static self ISO8859_2() 15 * @method static self ISO8859_3() 16 * @method static self ISO8859_4() 17 * @method static self ISO8859_5() 18 * @method static self ISO8859_6() 19 * @method static self ISO8859_7() 20 * @method static self ISO8859_8() 21 * @method static self ISO8859_9() 22 * @method static self ISO8859_10() 23 * @method static self ISO8859_11() 24 * @method static self ISO8859_12() 25 * @method static self ISO8859_13() 26 * @method static self ISO8859_14() 27 * @method static self ISO8859_15() 28 * @method static self ISO8859_16() 29 * @method static self SJIS() 30 * @method static self CP1250() 31 * @method static self CP1251() 32 * @method static self CP1252() 33 * @method static self CP1256() 34 * @method static self UNICODE_BIG_UNMARKED() 35 * @method static self UTF8() 36 * @method static self ASCII() 37 * @method static self BIG5() 38 * @method static self GB18030() 39 * @method static self EUC_KR() 40 */ 41final class CharacterSetEci extends AbstractEnum 42{ 43 protected const CP437 = [[0, 2]]; 44 protected const ISO8859_1 = [[1, 3], 'ISO-8859-1']; 45 protected const ISO8859_2 = [[4], 'ISO-8859-2']; 46 protected const ISO8859_3 = [[5], 'ISO-8859-3']; 47 protected const ISO8859_4 = [[6], 'ISO-8859-4']; 48 protected const ISO8859_5 = [[7], 'ISO-8859-5']; 49 protected const ISO8859_6 = [[8], 'ISO-8859-6']; 50 protected const ISO8859_7 = [[9], 'ISO-8859-7']; 51 protected const ISO8859_8 = [[10], 'ISO-8859-8']; 52 protected const ISO8859_9 = [[11], 'ISO-8859-9']; 53 protected const ISO8859_10 = [[12], 'ISO-8859-10']; 54 protected const ISO8859_11 = [[13], 'ISO-8859-11']; 55 protected const ISO8859_12 = [[14], 'ISO-8859-12']; 56 protected const ISO8859_13 = [[15], 'ISO-8859-13']; 57 protected const ISO8859_14 = [[16], 'ISO-8859-14']; 58 protected const ISO8859_15 = [[17], 'ISO-8859-15']; 59 protected const ISO8859_16 = [[18], 'ISO-8859-16']; 60 protected const SJIS = [[20], 'Shift_JIS']; 61 protected const CP1250 = [[21], 'windows-1250']; 62 protected const CP1251 = [[22], 'windows-1251']; 63 protected const CP1252 = [[23], 'windows-1252']; 64 protected const CP1256 = [[24], 'windows-1256']; 65 protected const UNICODE_BIG_UNMARKED = [[25], 'UTF-16BE', 'UnicodeBig']; 66 protected const UTF8 = [[26], 'UTF-8']; 67 protected const ASCII = [[27, 170], 'US-ASCII']; 68 protected const BIG5 = [[28]]; 69 protected const GB18030 = [[29], 'GB2312', 'EUC_CN', 'GBK']; 70 protected const EUC_KR = [[30], 'EUC-KR']; 71 72 /** 73 * @var int[] 74 */ 75 private $values; 76 77 /** 78 * @var string[] 79 */ 80 private $otherEncodingNames; 81 82 /** 83 * @var array<int, self>|null 84 */ 85 private static $valueToEci; 86 87 /** 88 * @var array<string, self>|null 89 */ 90 private static $nameToEci; 91 92 public function __construct(array $values, string ...$otherEncodingNames) 93 { 94 $this->values = $values; 95 $this->otherEncodingNames = $otherEncodingNames; 96 } 97 98 /** 99 * Returns the primary value. 100 */ 101 public function getValue() : int 102 { 103 return $this->values[0]; 104 } 105 106 /** 107 * Gets character set ECI by value. 108 * 109 * Returns the representing ECI of a given value, or null if it is legal but unsupported. 110 * 111 * @throws InvalidArgumentException if value is not between 0 and 900 112 */ 113 public static function getCharacterSetEciByValue(int $value) : ?self 114 { 115 if ($value < 0 || $value >= 900) { 116 throw new InvalidArgumentException('Value must be between 0 and 900'); 117 } 118 119 $valueToEci = self::valueToEci(); 120 121 if (! array_key_exists($value, $valueToEci)) { 122 return null; 123 } 124 125 return $valueToEci[$value]; 126 } 127 128 /** 129 * Returns character set ECI by name. 130 * 131 * Returns the representing ECI of a given name, or null if it is legal but unsupported 132 */ 133 public static function getCharacterSetEciByName(string $name) : ?self 134 { 135 $nameToEci = self::nameToEci(); 136 $name = strtolower($name); 137 138 if (! array_key_exists($name, $nameToEci)) { 139 return null; 140 } 141 142 return $nameToEci[$name]; 143 } 144 145 private static function valueToEci() : array 146 { 147 if (null !== self::$valueToEci) { 148 return self::$valueToEci; 149 } 150 151 self::$valueToEci = []; 152 153 foreach (self::values() as $eci) { 154 foreach ($eci->values as $value) { 155 self::$valueToEci[$value] = $eci; 156 } 157 } 158 159 return self::$valueToEci; 160 } 161 162 private static function nameToEci() : array 163 { 164 if (null !== self::$nameToEci) { 165 return self::$nameToEci; 166 } 167 168 self::$nameToEci = []; 169 170 foreach (self::values() as $eci) { 171 self::$nameToEci[strtolower($eci->name())] = $eci; 172 173 foreach ($eci->otherEncodingNames as $name) { 174 self::$nameToEci[strtolower($name)] = $eci; 175 } 176 } 177 178 return self::$nameToEci; 179 } 180} 181