stringparser.php

来自「Bug tracker, and reporter.」· PHP 代码 · 共 710 行 · 第 1/2 页

PHP
710
字号
        $openedBrackets = 1;        while ($this->offset < strlen($this->data)) {            switch (ord( $this->data[$this->offset] )) {                case 0x28: // '(' - opened bracket in the string, needs balanced pair.                    $openedBrackets++;                    break;                case 0x29: // ')' - pair to the opened bracket                    $openedBrackets--;                    break;                case 0x5C: // '\\' - escape sequence, skip next char from a check                    $this->offset++;            }            $this->offset++;            if ($openedBrackets == 0) {                break; // end of string            }        }        if ($openedBrackets != 0) {            throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Unexpected end of file while string reading. Offset - 0x%X. \')\' expected.', $start));        }        return new Zend_Pdf_Element_String(Zend_Pdf_Element_String::unescape( substr($this->data,                                                                 $start,                                                                 $this->offset - $start - 1) ));    }    /**     * Read binary string PDF object     * Also reads trailing '>' from a pdf stream     *     * @return Zend_Pdf_Element_String_Binary     * @throws Zend_Pdf_Exception     */    private function _readBinaryString()    {        $start = $this->offset;        while ($this->offset < strlen($this->data)) {            if (self::isWhiteSpace( ord($this->data[$this->offset]) ) ||                ctype_xdigit( $this->data[$this->offset] ) ) {                $this->offset++;            } else if ($this->data[$this->offset] == '>') {                $this->offset++;                return new Zend_Pdf_Element_String_Binary(                               Zend_Pdf_Element_String_Binary::unescape( substr($this->data,                                                                    $start,                                                                    $this->offset - $start - 1) ));            } else {                throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Unexpected character while binary string reading. Offset - 0x%X.', $this->offset));            }        }        throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Unexpected end of file while binary string reading. Offset - 0x%X. \'>\' expected.', $start));    }    /**     * Read array PDF object     * Also reads trailing ']' from a pdf stream     *     * @return Zend_Pdf_Element_Array     * @throws Zend_Pdf_Exception     */    private function _readArray()    {        $elements = array();        while ( strlen($nextLexeme = $this->readLexeme()) != 0 ) {            if ($nextLexeme != ']') {                $elements[] = $this->readElement($nextLexeme);            } else {                return new Zend_Pdf_Element_Array($elements);            }        }        throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Unexpected end of file while array reading. Offset - 0x%X. \']\' expected.', $this->offset));    }    /**     * Read dictionary PDF object     * Also reads trailing '>>' from a pdf stream     *     * @return Zend_Pdf_Element_Dictionary     * @throws Zend_Pdf_Exception     */    private function _readDictionary()    {        $dictionary = new Zend_Pdf_Element_Dictionary();        while ( strlen($nextLexeme = $this->readLexeme()) != 0 ) {            if ($nextLexeme != '>>') {                $nameStart = $this->offset - strlen($nextLexeme);                $name  = $this->readElement($nextLexeme);                $value = $this->readElement();                if (!$name instanceof Zend_Pdf_Element_Name) {                    throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Name object expected while dictionary reading. Offset - 0x%X.', $nameStart));                }                $dictionary->add($name, $value);            } else {                return $dictionary;            }        }        throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Unexpected end of file while dictionary reading. Offset - 0x%X. \'>>\' expected.', $this->offset));    }    /**     * Read reference PDF object     *     * @param string $nextLexeme     * @return Zend_Pdf_Element_Reference     */    private function _readReference($nextLexeme = null)    {        $start = $this->offset;        if ($nextLexeme === null) {            $objNum = $this->readLexeme();        } else {            $objNum = $nextLexeme;        }        if (!ctype_digit($objNum)) { // it's not a reference            $this->offset = $start;            return null;        }        $genNum = $this->readLexeme();        if (!ctype_digit($genNum)) { // it's not a reference            $this->offset = $start;            return null;        }        $rMark  = $this->readLexeme();        if ($rMark != 'R') { // it's not a reference            $this->offset = $start;            return null;        }        $ref = new Zend_Pdf_Element_Reference((int)$objNum, (int)$genNum, $this->_context, $this->_objFactory->resolve());        return $ref;    }    /**     * Read numeric PDF object     *     * @param string $nextLexeme     * @return Zend_Pdf_Element_Numeric     */    private function _readNumeric($nextLexeme = null)    {        if ($nextLexeme === null) {            $nextLexeme = $this->readLexeme();        }        return new Zend_Pdf_Element_Numeric($nextLexeme);    }    /**     * Read inderect object from a PDF stream     *     * @param integer $offset     * @param Zend_Pdf_Element_Reference_Context $context     * @return Zend_Pdf_Element_Object     */    public function getObject($offset, Zend_Pdf_Element_Reference_Context $context)    {        if ($offset === null ) {            return new Zend_Pdf_Element_Null();        }        // Save current offset to make getObject() reentrant        $offsetSave = $this->offset;        $this->offset    = $offset;        $this->_context  = $context;        $this->_elements = array();        $objNum = $this->readLexeme();        if (!ctype_digit($objNum)) {            throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Object number expected.', $this->offset - strlen($objNum)));        }        $genNum = $this->readLexeme();        if (!ctype_digit($genNum)) {            throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Object generation number expected.', $this->offset - strlen($genNum)));        }        $objKeyword = $this->readLexeme();        if ($objKeyword != 'obj') {            throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. \'obj\' keyword expected.', $this->offset - strlen($objKeyword)));        }        $objValue = $this->readElement();        $nextLexeme = $this->readLexeme();        if( $nextLexeme == 'endobj' ) {            /**             * Object is not generated by factory (thus it's not marked as modified object).             * But factory is assigned to the obect.             */            $obj = new Zend_Pdf_Element_Object($objValue, (int)$objNum, (int)$genNum, $this->_objFactory->resolve());            foreach ($this->_elements as $element) {                $element->setParentObject($obj);            }            // Restore offset value            $this->offset = $offsetSave;            return $obj;        }        /**         * It's a stream object         */        if ($nextLexeme != 'stream') {            throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. \'endobj\' or \'stream\' keywords expected.', $this->offset - strlen($nextLexeme)));        }        if (!$objValue instanceof Zend_Pdf_Element_Dictionary) {            throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Stream extent must be preceded by stream dictionary.', $this->offset - strlen($nextLexeme)));        }        /**         * References are automatically dereferenced at this moment.         */        $streamLength = $objValue->Length->value;        /**         * 'stream' keyword must be followed by either cr-lf sequence or lf character only.         * This restriction gives the possibility to recognize all cases exactly         */        if ($this->data[$this->offset] == "\r" &&            $this->data[$this->offset + 1] == "\n"    ) {            $this->offset += 2;        } else if ($this->data[$this->offset] == "\n"    ) {            $this->offset++;        } else {            throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. \'stream\' must be followed by either cr-lf sequence or lf character only.', $this->offset - strlen($nextLexeme)));        }        $dataOffset = $this->offset;        $this->offset += $streamLength;        $nextLexeme = $this->readLexeme();        if ($nextLexeme != 'endstream') {            throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. \'endstream\' keyword expected.', $this->offset - strlen($nextLexeme)));        }        $nextLexeme = $this->readLexeme();        if ($nextLexeme != 'endobj') {            throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. \'endobj\' keyword expected.', $this->offset - strlen($nextLexeme)));        }        $obj = new Zend_Pdf_Element_Object_Stream(substr($this->data,                                                         $dataOffset,                                                         $streamLength),                                                  (int)$objNum,                                                  (int)$genNum,                                                  $this->_objFactory->resolve(),                                                  $objValue);        foreach ($this->_elements as $element) {            $element->setParentObject($obj);        }        // Restore offset value        $this->offset = $offsetSave;        return $obj;    }    /**     * Get length of source string     *     * @return integer     */    public function getLength()    {        return strlen($this->data);    }    /**     * Get source string     *     * @return string     */    public function getString()    {        return $this->data;    }    /**     * Parse integer value from a binary stream     *     * @param string $stream     * @param integer $offset     * @param integer $size     * @return integer     */    public static function parseIntFromStream($stream, $offset, $size)    {        $value = 0;        for ($count = 0; $count < $size; $count++) {            $value *= 256;            $value += ord($stream[$offset + $count]);        }        return $value;    }    /**     * Set current context     *     * @param Zend_Pdf_Element_Reference_Context $context     */    public function setContext(Zend_Pdf_Element_Reference_Context $context)    {        $this->_context = $context;    }    /**     * Object constructor     *     * Note: PHP duplicates string, which is sent by value, only of it's updated.     * Thus we don't need to care about overhead     *     * @param string $pdfString     * @param Zend_Pdf_ElementFactory_Interface $factory     */    public function __construct($source, Zend_Pdf_ElementFactory_Interface $factory)    {        $this->data         = $source;        $this->_objFactory  = $factory;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?