Recursively parse BODYSTRUCTURE data from a FETCH return (see
RFC 3501 [7.4.2]).

@param Horde_Imap_Client_Tokenize $data  Data returned from the server.

@return Horde_Mime_Part  Mime part object.
970292
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;
    }
446587
public function parseBody() {
        $this->client->openFolder($this->folder_path);
        $this->structure = imap_fetchstructure($this->client->getConnection(), $this->uid, IMAP::FT_UID);

        if(property_exists($this->structure, 'parts')){
            $parts = $this->structure->parts;

            foreach ($parts as $part)  {
                foreach ($part->parameters as $parameter)  {
                    if($parameter->attribute == "charset")  {
                        $encoding = $parameter->value;

                        $encoding = preg_replace('/Content-Transfer-Encoding/', '', $encoding);
                        $encoding = preg_replace('/iso-8859-8-i/', 'iso-8859-8', $encoding);

                        $parameter->value = $encoding;
                    }
                }
            }
        }

        $this->fetchStructure($this->structure);

        return $this;
    }
341845
protected static function decode_chunked($data) {
		if (!preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', trim($data))) {
			return $data;
		}

		$decoded = '';
		$encoded = $data;

		while (true) {
			$is_chunked = (bool) preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', $encoded, $matches );
			if (!$is_chunked) {
				// Looks like it's not chunked after all
				return $data;
			}

			$length = hexdec(trim($matches[1]));
			if ($length === 0) {
				// Ignore trailer headers
				return $decoded;
			}

			$chunk_length = strlen($matches[0]);
			$decoded .= $part = substr($encoded, $chunk_length, $length);
			$encoded = substr($encoded, $chunk_length + $length + 2);

			if (trim($encoded) === '0' || empty($encoded)) {
				return $decoded;
			}
		}

		// We'll never actually get down here
		// @codeCoverageIgnoreStart
	}
681101
public function parse($data)
    {
        $this->table();
        $this->images();
        $this->text();
        $this->html();

        // Replace everything that has been found
        foreach ($this->matches as $key => $val) {
            $data = preg_replace_callback($key, $val, $data);
        }

        // Replace line-breaks
        return preg_replace_callback("/\n\r?/", function () {
            return '<br />';
        }, $data
        );
    }
415072
private function parseIniString($data)
    {
        $config = $this->arr();
        $data = parse_ini_string($data, true);
        foreach ($data as $section => $value) {
            $config = $config->mergeRecursive($this->processValue($section, $value));
        }

        return $config;
    }
693007
protected function _parseNamespace(
        Horde_Imap_Client_Interaction_Pipeline $pipeline,
        Horde_Imap_Client_Tokenize $data
    )
    {
        $namespace_array = array(
            Horde_Imap_Client_Data_Namespace::NS_PERSONAL,
            Horde_Imap_Client_Data_Namespace::NS_OTHER,
            Horde_Imap_Client_Data_Namespace::NS_SHARED
        );

        $c = array();

        // Per RFC 2342, response from NAMESPACE command is:
        // (PERSONAL NAMESPACES) (OTHER_USERS NAMESPACE) (SHARED NAMESPACES)
        foreach ($namespace_array as $val) {
            $entry = $data->next();

            if (is_null($entry)) {
                continue;
            }

            while ($data->next() !== false) {
                $ob = Horde_Imap_Client_Mailbox::get($data->next(), true);

                $ns = new Horde_Imap_Client_Data_Namespace();
                $ns->delimiter = $data->next();
                $ns->name = strval($ob);
                $ns->type = $val;
                $c[strval($ob)] = $ns;

                // RFC 4466: NAMESPACE extensions
                while (($ext = $data->next()) !== false) {
                    switch (Horde_String::upper($ext)) {
                    case 'TRANSLATION':
                        // RFC 5255 [3.4] - TRANSLATION extension
                        $data->next();
                        $ns->translation = $data->next();
                        $data->next();
                        break;
                    }
                }
            }
        }

        $pipeline->data['namespace'] = new Horde_Imap_Client_Namespace_List($c);
    }
6578
protected function _parseQuota(
        Horde_Imap_Client_Interaction_Pipeline $pipeline,
        Horde_Imap_Client_Tokenize $data
    )
    {
        $c = &$pipeline->data['quotaresp'];

        $root = $data->next();
        $c[$root] = array();

        $data->next();

        while (($curr = $data->next()) !== false) {
            $c[$root][Horde_String::lower($curr)] = array(
                'usage' => $data->next(),
                'limit' => $data->next()
            );
        }
    }
1110478
public static function parse(string $data): self
    {
        $separator = strpos($data, "\r\n\r\n");

        if ($separator === false) {
            throw new FormatException('Invalid article format');
        }

        $headers = HeaderBag::parse(substr($data, 0, $separator + 2));
        $body = substr($data, $separator + 4);

        return new self($body, $headers);
    }
188225
public function setEnvelope($data)
    {
        $this->_data[Horde_Imap_Client::FETCH_ENVELOPE] = is_array($data)
            ? new Horde_Imap_Client_Data_Envelope($data)
            : $data;
    }
11885
public function create($data)
    {
        $response = $this->restClient->post($this->endpoint, $data);
        return $response['body'];
    }
514946
public function setText($data)
    {
        if (empty($data)) {
            throw new Exception('You must not call MimeMailParser::setText with an empty string parameter');
        }

        if (substr($data, -1) != "\n") {
            $data = $data.PHP_EOL;
        }

        $this->resource = mailparse_msg_create();
        // does not parse incrementally, fast memory hog might explode
        mailparse_msg_parse($this->resource, $data);
        $this->data = $data;
        $this->parse();

        return $this;
    }
859833
public function decode($data)
    {
        $add = $convert = array();

        if (is_array($data)) {
            $params = $data;
        } else {
            $parts = explode(';', $data, 2);
            if (isset($parts[0]) && (strpos($parts[0], '=') === false)) {
                $this->setContentParamValue($parts[0]);
                $param = isset($parts[1]) ? $parts[1] : null;
            } else {
                $param = $data;
            }

            if (empty($param)) {
                $params = array();
            } else {
                $decode = new Horde_Mime_ContentParam_Decode();
                $params = $decode->decode($param);
            }
        }

        $to_add = array();

        foreach ($params as $name => $val) {
            /* Asterisk at end indicates encoded value. */
            if (substr($name, -1) == '*') {
                $name = substr($name, 0, -1);
                $encoded = true;
            } else {
                $encoded = false;
            }

            /* This asterisk indicates continuation parameter. */
            if ((($pos = strrpos($name, '*')) !== false) &&
                is_numeric($order = substr($name, $pos + 1))) {
                $name = substr($name, 0, $pos);
                $to_add[Horde_String::lower($name)][$order] = $val;
            } else {
                $to_add[$name] = array($val);
            }

            if ($encoded) {
                $convert[$name] = true;
            }
        }

        foreach ($to_add as $key => $val) {
            ksort($val);
            $add[$key] = implode('', $val);
        }

        foreach (array_keys($convert) as $name) {
            $val = $add[$name];
            $quote = strpos($val, "'");

            if ($quote === false) {
                $add[$name] = urldecode($val);
            } else {
                $orig_charset = substr($val, 0, $quote);
                if (Horde_String::lower($orig_charset) == 'iso-8859-1') {
                    $orig_charset = 'windows-1252';
                }

                /* Ignore language. */
                $quote = strpos($val, "'", $quote + 1);
                substr($val, $quote + 1);
                $add[$name] = Horde_String::convertCharset(
                    urldecode(substr($val, $quote + 1)),
                    $orig_charset,
                    'UTF-8'
                );
            }
        }

        /* MIME parameters are supposed to be encoded via RFC 2231, but many
         * mailers do RFC 2045 encoding instead. However, if we see at least
         * one RFC 2231 encoding, then assume the sending mailer knew what
         * it was doing and didn't send any parameters RFC 2045 encoded. */
        if (empty($convert)) {
            foreach ($add as $key => $val) {
                $add[$key] = Horde_Mime::decode($val);
            }
        }

        if (count($add)) {
            foreach ($add as $key => $val) {
                /* When parsing a content-param string, lowercase all
                 * parameter names to normalize. Only maintain case of
                 * parameters explicitly added by calling code. */
                $this[Horde_String::lower($key)] = $val;
            }
        } elseif (is_string($data)) {
            $this->setContentParamValue($parts[0]);
        }
    }
753016
private function is_bulk_message(
            \Horde_Imap_Client_Data_Fetch $message,
            $messageid) {
        $query = new \Horde_Imap_Client_Fetch_Query();
        $query->headerText(array('peek' => true));

        $messagedata = $this->client->fetch($this->get_mailbox(), $query, array('ids' => $messageid))->first();

        // Assume that this message is not bulk to begin with.
        $isbulk = false;

        // An auto-reply may itself include the Bulk Precedence.
        $precedence = $messagedata->getHeaderText(0, \Horde_Imap_Client_Data_Fetch::HEADER_PARSE)->getValue('Precedence');
        $isbulk = $isbulk || strtolower($precedence) == 'bulk';

        // If the X-Autoreply header is set, and not 'no', then this is an automatic reply.
        $autoreply = $messagedata->getHeaderText(0, \Horde_Imap_Client_Data_Fetch::HEADER_PARSE)->getValue('X-Autoreply');
        $isbulk = $isbulk || ($autoreply && $autoreply != 'no');

        // If the X-Autorespond header is set, and not 'no', then this is an automatic response.
        $autorespond = $messagedata->getHeaderText(0, \Horde_Imap_Client_Data_Fetch::HEADER_PARSE)->getValue('X-Autorespond');
        $isbulk = $isbulk || ($autorespond && $autorespond != 'no');

        // If the Auto-Submitted header is set, and not 'no', then this is a non-human response.
        $autosubmitted = $messagedata->getHeaderText(0, \Horde_Imap_Client_Data_Fetch::HEADER_PARSE)->getValue('Auto-Submitted');
        $isbulk = $isbulk || ($autosubmitted && $autosubmitted != 'no');

        return $isbulk;
    }
1155384
protected function _parseVanished(
        Horde_Imap_Client_Interaction_Pipeline $pipeline,
        Horde_Imap_Client_Tokenize $data
    )
    {
        /* There are two forms of VANISHED.  VANISHED (EARLIER) will be sent
         * in a FETCH (VANISHED) or SELECT/EXAMINE (QRESYNC) call.
         * If this is the case, we can go ahead and update the cache
         * immediately (we know we are caching or else QRESYNC would not be
         * enabled). HIGHESTMODSEQ information will be updated via the tagged
         * response. */
        if (($curr = $data->next()) === true) {
            if (Horde_String::upper($data->next()) === 'EARLIER') {
                /* Caching is guaranteed to be active if we are using
                 * QRESYNC. */
                $data->next();
                $vanished = $this->getIdsOb($data->next());
                if (isset($pipeline->data['vanished'])) {
                    $pipeline->data['vanished']->add($vanished);
                } else {
                    $this->_deleteMsgs($this->_selected, $vanished, array(
                        'pipeline' => $pipeline
                    ));
                }
            }
        } else {
            /* The second form is just VANISHED. This is analogous to EXPUNGE
             * and requires the message count to decrement. */
            $this->_deleteMsgs($this->_selected, $this->getIdsOb($curr), array(
                'decrement' => true,
                'pipeline' => $pipeline
            ));
        }
    }
836203
private function parse_body(&$body)
    {
        // Mail_mimeDecode need \r\n end-line, but gpg may return \n
        $body = preg_replace('/\r?\n/', "\r\n", $body);

        // parse the body into structure
        $struct = rcube_mime::parse_message($body);

        return $struct;
    }
96033
public function parse($data)
    {
        if ($data === null || !is_string($data)) {
            return array();
        }

        if (substr($data, 0, 1) !== '{' &&
            substr($data, 0, 1) !== '[') {
            return array();
        }

        return (array) json_decode($data, true);
    }
158069
public function parse(MimePart $part)
    {
        if (!$this->middleware) {
            return $part;
        }
        $part = call_user_func(array($this->middleware, 'parse'), $part, $this->next);
        return $part;
    }