roundcubemail/program/lib/Roundcube/rcube_result_thread.php
protected function parse_thread($str, $begin = 0, $end = 0, $depth = 0)
    {
        // Don't be tempted to change $str to pass by reference to speed this up - it will slow it down by about
        // 7 times instead :-) See comments on http://uk2.php.net/references and this article:
        // http://derickrethans.nl/files/phparch-php-variables-article.pdf
        $node = '';
        if (!$end) {
            $end = strlen($str);
        }

        // Let's try to store data in max. compacted stracture as a string,
        // arrays handling is much more expensive
        // For the following structure: THREAD (2)(3 6 (4 23)(44 7 96))
        // -- 2
        // -- 3
        //     \-- 6
        //         |-- 4
        //         |    \-- 23
        //         |
        //         \-- 44
        //               \-- 7
        //                    \-- 96
        //
        // The output will be: 2,3^1:6^2:4^3:23^2:44^3:7^4:96

        if ($str[$begin] != '(') {
            // find next bracket
            $stop      = $begin + strcspn($str, '()', $begin, $end - $begin);
            $messages  = explode(' ', trim(substr($str, $begin, $stop - $begin)));

            if (empty($messages)) {
                return $node;
            }

            foreach ($messages as $msg) {
                if ($msg) {
                    $node .= ($depth ? self::SEPARATOR_ITEM.$depth.self::SEPARATOR_LEVEL : '').$msg;
                    $this->meta['messages']++;
                    $depth++;
                }
            }

            if ($stop < $end) {
                $node .= $this->parse_thread($str, $stop, $end, $depth);
            }
        }
        else {
            $off = $begin;
            while ($off < $end) {
                $start = $off;
                $off++;
                $n = 1;
                while ($n > 0) {
                    $p = strpos($str, ')', $off);
                    if ($p === false) {
                        // error, wrong structure, mismatched brackets in IMAP THREAD response
                        // @TODO: write error to the log or maybe set $this->raw_data = null;
                        return $node;
                    }
                    $p1 = strpos($str, '(', $off);
                    if ($p1 !== false && $p1 < $p) {
                        $off = $p1 + 1;
                        $n++;
                    }
                    else {
                        $off = $p + 1;
                        $n--;
                    }
                }

                $thread = $this->parse_thread($str, $start + 1, $off - 1, $depth);
                if ($thread) {
                    if (!$depth) {
                        if ($node) {
                            $node .= self::SEPARATOR_ELEMENT;
                        }
                    }
                    $node .= $thread;
                }
            }
        }

        return $node;
    }
protected function parse_thread($str, $begin = 0, $end = 0, $depth = 0)
    {
        // Don't be tempted to change $str to pass by reference to speed this up - it will slow it down by about
        // 7 times instead :-) See comments on http://uk2.php.net/references and this article:
        // http://derickrethans.nl/files/phparch-php-variables-article.pdf
        $node = '';
        if (!$end) {
            $end = strlen($str);
        }

        // Let's try to store data in max. compacted stracture as a string,
        // arrays handling is much more expensive
        // For the following structure: THREAD (2)(3 6 (4 23)(44 7 96))
        // -- 2
        // -- 3
        //     \-- 6
        //         |-- 4
        //         |    \-- 23
        //         |
        //         \-- 44
        //               \-- 7
        //                    \-- 96
        //
        // The output will be: 2,3^1:6^2:4^3:23^2:44^3:7^4:96

        if ($str[$begin] != '(') {
            // find next bracket
            $stop      = $begin + strcspn($str, '()', $begin, $end - $begin);
            $messages  = explode(' ', trim(substr($str, $begin, $stop - $begin)));

            if (empty($messages)) {
                return $node;
            }

            foreach ($messages as $msg) {
                if ($msg) {
                    $node .= ($depth ? self::SEPARATOR_ITEM.$depth.self::SEPARATOR_LEVEL : '').$msg;
                    $this->meta['messages']++;
                    $depth++;
                }
            }

            if ($stop < $end) {
                $node .= $this->parse_thread($str, $stop, $end, $depth);
            }
        }
        else {
            $off = $begin;
            while ($off < $end) {
                $start = $off;
                $off++;
                $n = 1;
                while ($n > 0) {
                    $p = strpos($str, ')', $off);
                    if ($p === false) {
                        // error, wrong structure, mismatched brackets in IMAP THREAD response
                        // @TODO: write error to the log or maybe set $this->raw_data = null;
                        return $node;
                    }
                    $p1 = strpos($str, '(', $off);
                    if ($p1 !== false && $p1 < $p) {
                        $off = $p1 + 1;
                        $n++;
                    }
                    else {
                        $off = $p + 1;
                        $n--;
                    }
                }

                $thread = $this->parse_thread($str, $start + 1, $off - 1, $depth);
                if ($thread) {
                    if (!$depth) {
                        if ($node) {
                            $node .= self::SEPARATOR_ELEMENT;
                        }
                    }
                    $node .= $thread;
                }
            }
        }

        return $node;
    }
protected function parse_thread ( $ str , $ begin = 0 , $ end = 0 , $ depth = 0 ) { // Don't be tempted to change $str to pass by reference to speed this up - it will slow it down by about // 7 times instead :-) See comments on http://uk2.php.net/references and this article: // http://derickrethans.nl/files/phparch-php-variables-article.pdf $ node = '' ; if ( ! $ end ) { $ end = strlen ( $ str ) ; } // Let's try to store data in max. compacted stracture as a string, // arrays handling is much more expensive // For the following structure: THREAD (2)(3 6 (4 23)(44 7 96)) // -- 2 // -- 3 //     \-- 6 //         |-- 4 //         |    \-- 23 //         | //         \-- 44 //               \-- 7 //                    \-- 96 // // The output will be: 2,3^1:6^2:4^3:23^2:44^3:7^4:96 if ( $ str [ $ begin ] != '(' ) { // find next bracket $ stop = $ begin + strcspn ( $ str , '()' , $ begin , $ end - $ begin ) ; $ messages = explode ( ' ' , trim ( substr ( $ str , $ begin , $ stop - $ begin ) ) ) ; if ( empty ( $ messages ) ) { return $ node ; } foreach ( $ messages as $ msg ) { if ( $ msg ) { $ node .= ( $ depth ? self :: SEPARATOR_ITEM . $ depth . self :: SEPARATOR_LEVEL : '' ) . $ msg ; $ this -> meta [ 'messages' ] ++ ; $ depth ++ ; } } if ( $ stop < $ end ) { $ node .= $ this -> parse_thread ( $ str , $ stop , $ end , $ depth ) ; } } else { $ off = $ begin ; while ( $ off < $ end ) { $ start = $ off ; $ off ++ ; $ n = 1 ; while ( $ n > 0 ) { $ p = strpos ( $ str , ')' , $ off ) ; if ( $ p === false ) { // error, wrong structure, mismatched brackets in IMAP THREAD response // @TODO: write error to the log or maybe set $this->raw_data = null; return $ node ; } $ p1 = strpos ( $ str , '(' , $ off ) ; if ( $ p1 !== false && $ p1 < $ p ) { $ off = $ p1 + 1 ; $ n ++ ; } else { $ off = $ p + 1 ; $ n -- ; } } $ thread = $ this -> parse_thread ( $ str , $ start + 1 , $ off - 1 , $ depth ) ; if ( $ thread ) { if ( ! $ depth ) { if ( $ node ) { $ node .= self :: SEPARATOR_ELEMENT ; } } $ node .= $ thread ; } } } return $ node ; }
IMAP THREAD response parser
IMAP THREAD response parser