# woocommerce-pos/1.10.7/vendor_prefixed/chillerlan/php-qrcode/src/Data/ECI.php

WCPOS – Point of Sale (POS) plugin for WooCommerce, version 1.10.7. 148 lines.

- Page: https://pluginprobe.com/plugins/woocommerce-pos/1.10.7/code/vendor_prefixed/chillerlan/php-qrcode/src/Data/ECI.php
- Raw: https://pluginprobe.com/plugins/woocommerce-pos/1.10.7/raw/vendor_prefixed/chillerlan/php-qrcode/src/Data/ECI.php
- Modified: 2026-06-09T13:55:26+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/woocommerce-pos/1.10.7/code/vendor_prefixed/chillerlan/php-qrcode/src/Data/ECI.php#L10-L20`.

```php
<?php

/**
 * Class ECI
 *
 * @created      20.11.2020
 * @author       smiley <smiley@chillerlan.net>
 * @copyright    2020 smiley
 * @license      MIT
 */
namespace WCPOS\Vendor\chillerlan\QRCode\Data;

use WCPOS\Vendor\chillerlan\QRCode\Common\BitBuffer;
use WCPOS\Vendor\chillerlan\QRCode\Common\ECICharset;
use WCPOS\Vendor\chillerlan\QRCode\Common\Mode;
use function mb_convert_encoding, mb_detect_encoding, mb_internal_encoding, sprintf;
/**
 * Adds an ECI Designator
 *
 * ISO/IEC 18004:2000 8.4.1.1
 *
 * Please note that you have to take care for the correct data encoding when adding with QRCode::add*Segment()
 */
final class ECI extends QRDataModeAbstract
{
    /**
     * @inheritDoc
     */
    public const DATAMODE = Mode::ECI;
    /**
     * The current ECI encoding id
     */
    private int $encoding;
    /**
     * @inheritDoc
     * @throws \chillerlan\QRCode\Data\QRCodeDataException
     * @noinspection PhpMissingParentConstructorInspection
     */
    public function __construct(int $encoding)
    {
        if ($encoding < 0 || $encoding > 999999) {
            throw new QRCodeDataException(sprintf('invalid encoding id: "%s"', $encoding));
        }
        $this->encoding = $encoding;
    }
    /**
     * @inheritDoc
     */
    public function getLengthInBits() : int
    {
        if ($this->encoding < 128) {
            return 8;
        }
        if ($this->encoding < 16384) {
            return 16;
        }
        return 24;
    }
    /**
     * Writes an ECI designator to the bitbuffer
     *
     * @inheritDoc
     * @throws \chillerlan\QRCode\Data\QRCodeDataException
     */
    public function write(BitBuffer $bitBuffer, int $versionNumber) : QRDataModeInterface
    {
        $bitBuffer->put(self::DATAMODE, 4);
        if ($this->encoding < 128) {
            $bitBuffer->put($this->encoding, 8);
        } elseif ($this->encoding < 16384) {
            $bitBuffer->put($this->encoding | 0x8000, 16);
        } elseif ($this->encoding < 1000000) {
            $bitBuffer->put($this->encoding | 0xc00000, 24);
        } else {
            throw new QRCodeDataException('invalid ECI ID');
        }
        return $this;
    }
    /**
     * Reads and parses the value of an ECI designator
     *
     * @throws \chillerlan\QRCode\Data\QRCodeDataException
     */
    public static function parseValue(BitBuffer $bitBuffer) : ECICharset
    {
        $firstByte = $bitBuffer->read(8);
        // just one byte
        if (($firstByte & 0b10000000) === 0) {
            $id = $firstByte & 0b1111111;
        } elseif (($firstByte & 0b11000000) === 0b10000000) {
            $id = ($firstByte & 0b111111) << 8 | $bitBuffer->read(8);
        } elseif (($firstByte & 0b11100000) === 0b11000000) {
            $id = ($firstByte & 0b11111) << 16 | $bitBuffer->read(16);
        } else {
            throw new QRCodeDataException(sprintf('error decoding ECI value first byte: %08b', $firstByte));
            // @codeCoverageIgnore
        }
        return new ECICharset($id);
    }
    /**
     * @codeCoverageIgnore Unused, but required as per interface
     */
    public static function validateString(string $string) : bool
    {
        return \true;
    }
    /**
     * Reads and decodes the ECI designator including the following byte sequence
     *
     * @throws \chillerlan\QRCode\Data\QRCodeDataException
     */
    public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber) : string
    {
        $eciCharset = self::parseValue($bitBuffer);
        $nextMode = $bitBuffer->read(4);
        $data = self::decodeModeSegment($nextMode, $bitBuffer, $versionNumber);
        $encoding = $eciCharset->getName();
        if ($encoding === null) {
            // The spec isn't clear on this mode; see
            // section 6.4.5: it does not say which encoding to assuming
            // upon decoding. I have seen ISO-8859-1 used as well as
            // Shift_JIS -- without anything like an ECI designator to
            // give a hint.
            $encoding = mb_detect_encoding($data, ['ISO-8859-1', 'Windows-1252', 'SJIS', 'UTF-8'], \true);
            if ($encoding === \false) {
                throw new QRCodeDataException('could not determine encoding in ECI mode');
                // @codeCoverageIgnore
            }
        }
        return mb_convert_encoding($data, mb_internal_encoding(), $encoding);
    }
    /**
     * @throws \chillerlan\QRCode\Data\QRCodeDataException
     */
    private static function decodeModeSegment(int $mode, BitBuffer $bitBuffer, int $versionNumber) : string
    {
        switch (\true) {
            case $mode === Mode::NUMBER:
                return Number::decodeSegment($bitBuffer, $versionNumber);
            case $mode === Mode::ALPHANUM:
                return AlphaNum::decodeSegment($bitBuffer, $versionNumber);
            case $mode === Mode::BYTE:
                return Byte::decodeSegment($bitBuffer, $versionNumber);
        }
        throw new QRCodeDataException(sprintf('ECI designator followed by invalid mode: "%04b"', $mode));
    }
}

```
