Horde_Imap_Client_Socket::_parseBodystructure PHP Method

_parseBodystructure() protected method

Recursively parse BODYSTRUCTURE data from a FETCH return (see RFC 3501 [7.4.2]).
protected _parseBodystructure ( Horde_Imap_Client_Tokenize $data ) : Horde_Mime_Part
$data Horde_Imap_Client_Tokenize Data returned from the server.
return Horde_Mime_Part Mime part object.
    protected function _parseBodystructure(Horde_Imap_Client_Tokenize $data)
    {
        $ob = new Horde_Mime_Part();
        // If index 0 is an array, this is a multipart part.
        if (($entry = $data->next()) === true) {
            do {
                $ob->addPart($this->_parseBodystructure($data));
            } while (($entry = $data->next()) === true);
            // The subpart type.
            $ob->setType('multipart/' . $entry);
            // After the subtype is further extension information. This
            // information MAY appear for BODYSTRUCTURE requests.
            // This is parameter information.
            if (($tmp = $data->next()) === false) {
                return $ob;
            } elseif ($tmp === true) {
                foreach ($this->_parseStructureParams($data) as $key => $val) {
                    $ob->setContentTypeParameter($key, $val);
                }
            }
        } else {
            $ob->setType($entry . '/' . $data->next());
            if ($data->next() === true) {
                foreach ($this->_parseStructureParams($data) as $key => $val) {
                    $ob->setContentTypeParameter($key, $val);
                }
            }
            if (!is_null($tmp = $data->next())) {
                $ob->setContentId($tmp);
            }
            if (!is_null($tmp = $data->next())) {
                $ob->setDescription(Horde_Mime::decode($tmp));
            }
            $te = $data->next();
            $bytes = $data->next();
            if (!is_null($te)) {
                $ob->setTransferEncoding($te);
                /* Base64 transfer encoding is approx. 33% larger than
                 * original data size (RFC 2045 [6.8]). Return from
                 * BODYSTRUCTURE is the size of the ENCODED data (RFC 3501
                 * [7.4.2]). */
                if (strcasecmp($te, 'base64') === 0) {
                    $bytes *= 0.75;
                }
            }
            $ob->setBytes($bytes);
            // If the type is 'message/rfc822' or 'text/*', several extra
            // fields are included
            switch ($ob->getPrimaryType()) {
                case 'message':
                    if ($ob->getSubType() == 'rfc822') {
                        if ($data->next() === true) {
                            // Ignore: envelope
                            $data->flushIterator(false);
                        }
                        if ($data->next() === true) {
                            $ob->addPart($this->_parseBodystructure($data));
                        }
                        $data->next();
                        // Ignore: lines
                    }
                    break;
                case 'text':
                    $data->next();
                    // Ignore: lines
                    break;
            }
            // After the subtype is further extension information. This
            // information MAY appear for BODYSTRUCTURE requests.
            // Ignore: MD5
            if ($data->next() === false) {
                return $ob;
            }
        }
        // This is disposition information
        if (($tmp = $data->next()) === false) {
            return $ob;
        } elseif ($tmp === true) {
            $ob->setDisposition($data->next());
            if ($data->next() === true) {
                foreach ($this->_parseStructureParams($data) as $key => $val) {
                    $ob->setDispositionParameter($key, $val);
                }
            }
            $data->next();
        }
        // This is language information. It is either a single value or a list
        // of values.
        if (($tmp = $data->next()) === false) {
            return $ob;
        } elseif (!is_null($tmp)) {
            $ob->setLanguage($tmp === true ? $data->flushIterator() : $tmp);
        }
        // Ignore location (RFC 2557) and consume closing paren.
        $data->flushIterator(false);
        return $ob;
    }