Read byte string (8-bit string length)
OpenOffice documentation: 2.5.2

@param string $subData
@return array
427434
private function _readByteStringShort($subData)
	{
		// offset: 0; size: 1; length of the string (character count)
		$ln = ord($subData[0]);

		// offset: 1: size: var; character array (8-bit characters)
		$value = $this->_decodeCodepage(substr($subData, 1, $ln));

		return array(
			'value' => $value,
			'size' => 1 + $ln, // size in bytes of data structure
		);
	}
947551
private static function parseArray($val)
    {
        $result = array();
        $openBrackets = 0;
        $openString = false;
        $openLString = false;
        $buffer = '';

        $strLen = strlen($val);
        for($i = 0; $i < $strLen; $i++)
        {
            if($val[$i] == '[' && !$openString && !$openLString)
            {
                $openBrackets++;

                if($openBrackets == 1)
                {
                    // Skip first and last brackets.
                    continue;
                }
            }
            elseif($val[$i] == ']' && !$openString && !$openLString)
            {
                $openBrackets--;

                if($openBrackets == 0)
                {
                    // Allow terminating commas before the closing bracket
                    if(trim($buffer) != '')
                    {
                        $result[] = self::parseValue( trim($buffer) );
                    }

                    if (!self::checkDataType($result))
                    {
                        throw new Exception('Data types cannot be mixed in an array: ' . $buffer);
                    }
                    // Skip first and last brackets. We're finish.
                    return $result;
                }
            }
            elseif($val[$i] == '"' && $val[$i - 1] != "\\" && !$openLString)
            {
                $openString = !$openString;
            }
            elseif($val[$i] == "'"  && !$openString) {
                $openLString = !$openLString;
            }

            if( $val[$i] == ',' && !$openString && !$openLString && $openBrackets == 1)
            {
                $result[] = self::parseValue( trim($buffer) );

                if (!self::checkDataType($result))
                {
                    throw new Exception('Data types cannot be mixed in an array: ' . $buffer);
                }
                $buffer = '';
            }
            else
            {
                $buffer .= $val[$i];
            }
        }

        // If we're here, something went wrong.
        throw new Exception('Wrong array definition: ' . $val);
    }
847674
static public function getAllSubStrings($text)
    {
        $splitText = str_split($text);
        $splitCount = count($splitText);
        $subStrings = [];
        for ($i = 0; $i < $splitCount; $i++)
        {
            for ($j = $i; $j < $splitCount; $j++)
            {
                $subStrings[] = implode(array_slice($splitText, $i, $j - $i + 1));
            }
        }
        return $subStrings;
    }
882726
private function ordUtf8($text, $index = 0, $bytes = null)
    {
        $len = strlen($text);
        $bytes = 0;

        $char = false;

        if ($index < $len)
        {
            $h = ord($text{$index});

            if($h <= 0x7F)
            {
                $bytes = 1;
                $char = $h;
            }
            elseif ($h < 0xC2)
            {
                $char = false;
            }
            elseif ($h <= 0xDF && $index < $len - 1)
            {
                $bytes = 2;
                $char = ($h & 0x1F) <<  6 | (ord($text{$index + 1}) & 0x3F);
            }
            elseif($h <= 0xEF && $index < $len - 2)
            {
                $bytes = 3;
                $char = ($h & 0x0F) << 12 | (ord($text{$index + 1}) & 0x3F) << 6
                                         | (ord($text{$index + 2}) & 0x3F);
            }
            elseif($h <= 0xF4 && $index < $len - 3)
            {
                $bytes = 4;
                $char = ($h & 0x0F) << 18 | (ord($text{$index + 1}) & 0x3F) << 12
                                         | (ord($text{$index + 2}) & 0x3F) << 6
                                         | (ord($text{$index + 3}) & 0x3F);
            }
        }


        return array($char, $bytes);
    }
52505
private function sanitizeSubstitutionData(array $substitutionData)
    {
        $sanitized = [];

        foreach ($substitutionData as $key => $value) {
            $sanitized[(string) $key] = (string) $value;
        }

        return $sanitized;
    }
513128
private static function readBIFF8ConstantArray($arrayData)
    {
        // offset: 0; size: 1; number of columns decreased by 1
        $nc = ord($arrayData[0]);

        // offset: 1; size: 2; number of rows decreased by 1
        $nr = self::getInt2d($arrayData, 1);
        $size = 3; // initialize
        $arrayData = substr($arrayData, 3);

        // offset: 3; size: var; list of ($nc + 1) * ($nr + 1) constant values
        $matrixChunks = array();
        for ($r = 1; $r <= $nr + 1; ++$r) {
            $items = array();
            for ($c = 1; $c <= $nc + 1; ++$c) {
                $constant = self::_readBIFF8Constant($arrayData);
                $items[] = $constant['value'];
                $arrayData = substr($arrayData, $constant['size']);
                $size += $constant['size'];
            }
            $matrixChunks[] = implode(',', $items); // looks like e.g. '1,"hello"'
        }
        $matrix = '{' . implode(';', $matrixChunks) . '}';

        return array(
            'value' => $matrix,
            'size' => $size,
        );
    }
547898
protected function readBytes($bytes)
    {
        $data = '';
        $chunk = null;
        while ($bytes > 0 && false !== ($chunk = \fread($this->stream, $bytes))) {
            $bytes -= \strlen($chunk);
            $data .= $chunk;
        }

        if (false === $chunk) {
            throw new RuntimeException('Could not read from stream');
        }
        return $data;
    }
1034703
protected function readWav($readData = true)
    {
        if (!is_resource($this->_fp)) {
            throw new WavFileException('No wav file open. Use openWav() first.');
        }

        try {
            $this->readWavHeader();
        } catch (WavFileException $ex) {
            $this->closeWav();
            throw $ex;
        }

        if ($readData) return $this->readWavData();

        return $this;
    }
649787
private static function _readUnicodeStringLong($subData)
	{
		$value = '';

		// offset: 0: size: 2; length of the string (character count)
		$characterCount = self::_GetInt2d($subData, 0);

		$string = self::_readUnicodeString(substr($subData, 2), $characterCount);

		// add 2 for the string length
		$string['size'] += 2;

		return $string;
	}
643361
private static function _readBIFF8ConstantArray($arrayData)
	{
		// offset: 0; size: 1; number of columns decreased by 1
		$nc = ord($arrayData[0]);

		// offset: 1; size: 2; number of rows decreased by 1
		$nr = self::_GetInt2d($arrayData, 1);
		$size = 3; // initialize
		$arrayData = substr($arrayData, 3);

		// offset: 3; size: var; list of ($nc + 1) * ($nr + 1) constant values
		$matrixChunks = array();
		for ($r = 1; $r <= $nr + 1; ++$r) {
			$items = array();
			for ($c = 1; $c <= $nc + 1; ++$c) {
				$constant = self::_readBIFF8Constant($arrayData);
				$items[] = $constant['value'];
				$arrayData = substr($arrayData, $constant['size']);
				$size += $constant['size'];
			}
			$matrixChunks[] = implode(',', $items); // looks like e.g. '1,"hello"'
		}
		$matrix = '{' . implode(';', $matrixChunks) . '}';

		return array(
			'value' => $matrix,
			'size' => $size,
		);
	}
596172
public static function tokenize(string $plainData) : array
    {
        $tokens = [];

        if(! empty($plainData)) {
            $tokens = (new self($plainData))->tokenizeInternal()->tokens;
        }

        return $tokens;
    }
215698
protected function parseData($rawData)
    {
        $outputData = [];

        foreach (explode(' ', $rawData) as $data) {
            $data = explode(':', $data);
            $outputData[$data[0]] = $data[1];
        }

        return $outputData;
    }
559039
private function _readBIFF5CellRangeAddressFixed($subData)
	{
		// offset: 0; size: 2; index to first row
		$fr = self::_GetInt2d($subData, 0) + 1;

		// offset: 2; size: 2; index to last row
		$lr = self::_GetInt2d($subData, 2) + 1;

		// offset: 4; size: 1; index to first column
		$fc = ord($subData{4});

		// offset: 5; size: 1; index to last column
		$lc = ord($subData{5});

		// check values
		if ($fr > $lr || $fc > $lc) {
			throw new PHPExcel_Reader_Exception('Not a cell range address');
		}

		// column index to letter
		$fc = PHPExcel_Cell::stringFromColumnIndex($fc);
		$lc = PHPExcel_Cell::stringFromColumnIndex($lc);

		if ($fr == $lr and $fc == $lc) {
			return "$fc$fr";
		}
		return "$fc$fr:$lc$lr";
	}
903696
private function readList($size, $type)
    {
        $result = [];
        switch ($type) {
            case Compact::TYPE_TRUE:
            case Compact::TYPE_FALSE:
                for ($i = 0; $i < $size; $i++) {
                    $result[] = $this->readSignedByte() === Compact::TYPE_TRUE;
                }
                break;
            case Compact::TYPE_BYTE:
                for ($i = 0; $i < $size; $i++) {
                    $result[] = $this->readSignedByte();
                }
                break;
            case Compact::TYPE_I16:
            case Compact::TYPE_I32:
            case Compact::TYPE_I64:
                for ($i = 0; $i < $size; $i++) {
                    $result[] = $this->fromZigZag($this->readVarint());
                }
                break;
            case Compact::TYPE_BINARY:
                $result[] = $this->readString($this->readVarint());
                break;
        }

        return $result;
    }
377487
private function readBIFF5CellRangeAddressFixed($subData)
    {
        // offset: 0; size: 2; index to first row
        $fr = self::getInt2d($subData, 0) + 1;

        // offset: 2; size: 2; index to last row
        $lr = self::getInt2d($subData, 2) + 1;

        // offset: 4; size: 1; index to first column
        $fc = ord($subData{4});

        // offset: 5; size: 1; index to last column
        $lc = ord($subData{5});

        // check values
        if ($fr > $lr || $fc > $lc) {
            throw new PHPExcel_Reader_Exception('Not a cell range address');
        }

        // column index to letter
        $fc = PHPExcel_Cell::stringFromColumnIndex($fc);
        $lc = PHPExcel_Cell::stringFromColumnIndex($lc);

        if ($fr == $lr and $fc == $lc) {
            return "$fc$fr";
        }
        return "$fc$fr:$lc$lr";
    }
129158
protected function readSubBlock($block)
    {
        // remove terminatorByte cause it's always the same
        $block = substr($block, 0, -8);

        $length = strlen($block);
        $offset = 0;
        $data = [];
        while ($offset < $length) {
            $blockLength = hexdec(substr(substr($block, $offset, 8), -4)) / 256;
            $offset += 8;
            $data[] = hex2bin(substr($block, $offset, $blockLength * 2));
            $offset += $blockLength * 2;
        }

        if (3 == count($data)) {
            $data[] = $data[2];
            $data[2] = '';
        }

        $data[] = $this->createByte('00');

        return $data;
    }
1126765
public function load($data)
    {
        $this->data = $data;

        // total byte size of Excel data (workbook global substream + sheet substreams)
        $this->dataSize = strlen($this->data);

        $this->pos = 0;

        // Parse Escher stream
        while ($this->pos < $this->dataSize) {
            // offset: 2; size: 2: Record Type
            $fbt = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos + 2);

            switch ($fbt) {
                case self::DGGCONTAINER:
                    $this->readDggContainer();
                    break;
                case self::DGG:
                    $this->readDgg();
                    break;
                case self::BSTORECONTAINER:
                    $this->readBstoreContainer();
                    break;
                case self::BSE:
                    $this->readBSE();
                    break;
                case self::BLIPJPEG:
                    $this->readBlipJPEG();
                    break;
                case self::BLIPPNG:
                    $this->readBlipPNG();
                    break;
                case self::OPT:
                    $this->readOPT();
                    break;
                case self::TERTIARYOPT:
                    $this->readTertiaryOPT();
                    break;
                case self::SPLITMENUCOLORS:
                    $this->readSplitMenuColors();
                    break;
                case self::DGCONTAINER:
                    $this->readDgContainer();
                    break;
                case self::DG:
                    $this->readDg();
                    break;
                case self::SPGRCONTAINER:
                    $this->readSpgrContainer();
                    break;
                case self::SPCONTAINER:
                    $this->readSpContainer();
                    break;
                case self::SPGR:
                    $this->readSpgr();
                    break;
                case self::SP:
                    $this->readSp();
                    break;
                case self::CLIENTTEXTBOX:
                    $this->readClientTextbox();
                    break;
                case self::CLIENTANCHOR:
                    $this->readClientAnchor();
                    break;
                case self::CLIENTDATA:
                    $this->readClientData();
                    break;
                default:
                    $this->readDefault();
                    break;
            }
        }

        return $this->object;
    }