Mantis Bugtracker
  

Viewing Issue Advanced Details Jump to Notes ] View Simple ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0002875 [Quercus] major always 08-27-08 04:40 02-22-09 20:22
Reporter foxcold View Status public  
Assigned To
Priority normal Resolution open Platform
Status new   OS
Projection none   OS Version
ETA none Fixed in Version Product Version 3.2.1
  Product Build
Summary 0002875: OutOfMemoryError
Description
&20005;&37325;: Servlet.service() for servlet Quercus Servlet threw exception
com.caucho.quercus.QuercusModuleException: java.lang.OutOfMemoryError: Java heap space
    at com.caucho.quercus.QuercusModuleException.create(QuercusModuleException.java:64)
    at com.caucho.quercus.module.StaticFunction.invoke(StaticFunction.java:159)
    at com.caucho.quercus.env.JavaInvoker.callMethod(JavaInvoker.java:604)
    at com.caucho.quercus.env.JavaInvoker.call(JavaInvoker.java:539)
    at com.caucho.quercus.expr.FunctionExpr.evalImpl(FunctionExpr.java:182)
    at com.caucho.quercus.expr.FunctionExpr.eval(FunctionExpr.java:126)
    at com.caucho.quercus.program.ReturnStatement.execute(ReturnStatement.java:68)
    at com.caucho.quercus.program.IfStatement.execute(IfStatement.java:84)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.call(Function.java:292)
    at com.caucho.quercus.program.AbstractFunction.callMethod(AbstractFunction.java:309)
    at com.caucho.quercus.env.ObjectExtValue.callMethod(ObjectExtValue.java:602)
    at com.caucho.quercus.expr.MethodCallExpr.eval(MethodCallExpr.java:104)
    at com.caucho.quercus.expr.Expr.evalCopy(Expr.java:398)
    at com.caucho.quercus.expr.AssignExpr.eval(AssignExpr.java:86)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.call(Function.java:292)
    at com.caucho.quercus.program.AbstractFunction.callMethod(AbstractFunction.java:309)
    at com.caucho.quercus.env.ObjectExtValue.callMethod(ObjectExtValue.java:602)
    at com.caucho.quercus.expr.MethodCallExpr.eval(MethodCallExpr.java:104)
    at com.caucho.quercus.expr.Expr.evalCopy(Expr.java:398)
    at com.caucho.quercus.expr.AssignExpr.eval(AssignExpr.java:86)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.ForStatement.execute(ForStatement.java:76)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.IfStatement.execute(IfStatement.java:81)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.call(Function.java:292)
    at com.caucho.quercus.program.AbstractFunction.callMethod(AbstractFunction.java:309)
    at com.caucho.quercus.env.ObjectExtValue.callMethod(ObjectExtValue.java:602)
    at com.caucho.quercus.expr.MethodCallExpr.eval(MethodCallExpr.java:104)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.call(Function.java:292)
    at com.caucho.quercus.program.AbstractFunction.callMethod(AbstractFunction.java:309)
    at com.caucho.quercus.env.ObjectExtValue.callMethod(ObjectExtValue.java:602)
    at com.caucho.quercus.expr.MethodCallExpr.eval(MethodCallExpr.java:104)
    at com.caucho.quercus.program.Function.evalArguments(Function.java:194)
    at com.caucho.quercus.expr.FunctionExpr.evalImpl(FunctionExpr.java:170)
    at com.caucho.quercus.expr.FunctionExpr.eval(FunctionExpr.java:126)
    at com.caucho.quercus.program.ReturnStatement.execute(ReturnStatement.java:68)
    at com.caucho.quercus.program.IfStatement.execute(IfStatement.java:81)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.call(Function.java:292)
    at com.caucho.quercus.expr.FunctionExpr.evalImpl(FunctionExpr.java:182)
    at com.caucho.quercus.expr.FunctionExpr.eval(FunctionExpr.java:126)
    at com.caucho.quercus.program.ReturnStatement.execute(ReturnStatement.java:68)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.callCopy(Function.java:297)
    at com.caucho.quercus.expr.FunctionExpr.evalImpl(FunctionExpr.java:180)
    at com.caucho.quercus.expr.FunctionExpr.evalCopy(FunctionExpr.java:150)
    at com.caucho.quercus.expr.AssignExpr.eval(AssignExpr.java:86)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.call(Function.java:292)
    at com.caucho.quercus.program.AbstractFunction.callMethod(AbstractFunction.java:309)
    at com.caucho.quercus.env.ObjectExtValue.callMethod(ObjectExtValue.java:602)
    at com.caucho.quercus.expr.MethodCallExpr.eval(MethodCallExpr.java:104)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.call(Function.java:292)
    at com.caucho.quercus.program.AbstractFunction.callMethod(AbstractFunction.java:309)
    at com.caucho.quercus.env.QuercusClass.callNew(QuercusClass.java:698)
    at com.caucho.quercus.expr.NewExpr.eval(NewExpr.java:97)
    at com.caucho.quercus.expr.Expr.evalRef(Expr.java:386)
    at com.caucho.quercus.expr.AssignRefExpr.eval(AssignRefExpr.java:74)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.QuercusProgram.execute(QuercusProgram.java:272)
    at com.caucho.quercus.page.InterpretedPage.execute(InterpretedPage.java:70)
    at com.caucho.quercus.env.Env.include(Env.java:3730)
    at com.caucho.quercus.env.Env.includeOnce(Env.java:3679)
    at com.caucho.quercus.expr.IncludeOnceExpr.eval(IncludeOnceExpr.java:88)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.QuercusProgram.execute(QuercusProgram.java:272)
    at com.caucho.quercus.page.InterpretedPage.execute(InterpretedPage.java:70)
    at com.caucho.quercus.env.Env.include(Env.java:3730)
    at com.caucho.quercus.env.Env.includeOnce(Env.java:3679)
    at com.caucho.quercus.expr.IncludeOnceExpr.eval(IncludeOnceExpr.java:88)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.IfStatement.execute(IfStatement.java:81)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.QuercusProgram.execute(QuercusProgram.java:272)
    at com.caucho.quercus.page.InterpretedPage.execute(InterpretedPage.java:70)
    at com.caucho.quercus.env.Env.include(Env.java:3730)
    at com.caucho.quercus.env.Env.includeOnce(Env.java:3679)
    at com.caucho.quercus.expr.IncludeOnceExpr.eval(IncludeOnceExpr.java:88)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.IfStatement.execute(IfStatement.java:81)
    at com.caucho.quercus.program.QuercusProgram.execute(QuercusProgram.java:272)
    at com.caucho.quercus.page.InterpretedPage.execute(InterpretedPage.java:70)
    at com.caucho.quercus.env.Env.include(Env.java:3730)
    at com.caucho.quercus.expr.IncludeExpr.eval(IncludeExpr.java:86)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.QuercusProgram.execute(QuercusProgram.java:272)
    at com.caucho.quercus.page.InterpretedPage.execute(InterpretedPage.java:70)
    at com.caucho.quercus.page.QuercusPage.executeTop(QuercusPage.java:119)
    at com.caucho.quercus.servlet.QuercusServletImpl.service(QuercusServletImpl.java:165)
    at com.caucho.quercus.servlet.QuercusServlet.service(QuercusServlet.java:355)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.OutOfMemoryError: Java heap space
    at com.caucho.quercus.env.StringBuilderValue.<init>(StringBuilderValue.java:71)
    at com.caucho.quercus.env.StringBuilderValue.subSequence(StringBuilderValue.java:667)
    at com.caucho.quercus.env.StringValue.substring(StringValue.java:1618)
    at com.caucho.quercus.lib.string.StringModule.substr(StringModule.java:3926)
    at sun.reflect.GeneratedMethodAccessor30.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.caucho.quercus.module.StaticFunction.invoke(StaticFunction.java:129)
    at com.caucho.quercus.env.JavaInvoker.callMethod(JavaInvoker.java:604)
    at com.caucho.quercus.env.JavaInvoker.call(JavaInvoker.java:539)
    at com.caucho.quercus.expr.FunctionExpr.evalImpl(FunctionExpr.java:182)
    at com.caucho.quercus.expr.FunctionExpr.eval(FunctionExpr.java:126)
    at com.caucho.quercus.program.ReturnStatement.execute(ReturnStatement.java:68)
    at com.caucho.quercus.program.IfStatement.execute(IfStatement.java:84)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.call(Function.java:292)
    at com.caucho.quercus.program.AbstractFunction.callMethod(AbstractFunction.java:309)
    at com.caucho.quercus.env.ObjectExtValue.callMethod(ObjectExtValue.java:602)
    at com.caucho.quercus.expr.MethodCallExpr.eval(MethodCallExpr.java:104)
    at com.caucho.quercus.expr.Expr.evalCopy(Expr.java:398)
    at com.caucho.quercus.expr.AssignExpr.eval(AssignExpr.java:86)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at com.caucho.quercus.program.Function.callImpl(Function.java:352)
    at com.caucho.quercus.program.Function.call(Function.java:292)
    at com.caucho.quercus.program.AbstractFunction.callMethod(AbstractFunction.java:309)
    at com.caucho.quercus.env.ObjectExtValue.callMethod(ObjectExtValue.java:602)
    at com.caucho.quercus.expr.MethodCallExpr.eval(MethodCallExpr.java:104)
    at com.caucho.quercus.expr.Expr.evalCopy(Expr.java:398)
    at com.caucho.quercus.expr.AssignExpr.eval(AssignExpr.java:86)
    at com.caucho.quercus.program.ExprStatement.execute(ExprStatement.java:64)
    at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
    at gettext_reader.load_tables(/F:/Work/java_workspace/.metadata/.plugins/com.genuitec.eclipse.easie.tomcat.myeclipse/tomcat/webapps/php/blog/wp-includes/gettext.php:162)
Steps To Reproduce
Additional Information <?php
/**
 * PHP-Gettext External Library: gettext_reader class
 *
 * @package External
 * @subpackage PHP-gettext
 *
 * @internal
     Copyright (c) 2003 Danilo Segan <danilo@kvota.net>.
     Copyright (c) 2005 Nico Kaiser <nico@siriux.net>

     This file is part of PHP-gettext.

     PHP-gettext is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.

     PHP-gettext is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with PHP-gettext; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

*/

/**
 * Provides a simple gettext replacement that works independently from
 * the system's gettext abilities.
 * It can read MO files and use them for translating strings.
 * The files are passed to gettext_reader as a Stream (see streams.php)
 *
 * This version has the ability to cache all strings and translations to
 * speed up the string lookup.
 * While the cache is enabled by default, it can be switched off with the
 * second parameter in the constructor (e.g. whenusing very large MO files
 * that you don't want to keep in memory)
 */
class gettext_reader {
    //public:
     var $error = 0; // public variable that holds error code (0 if no error)

     //private:
    var $BYTEORDER = 0; // 0: low endian, 1: big endian
    var $STREAM = NULL;
    var $short_circuit = false;
    var $enable_cache = false;
    var $originals = NULL; // offset of original table
    var $translations = NULL; // offset of translation table
    var $pluralheader = NULL; // cache header field for plural forms
    var $select_string_function = NULL; // cache function, which chooses plural forms
    var $total = 0; // total string count
    var $table_originals = NULL; // table for original strings (offsets)
    var $table_translations = NULL; // table for translated strings (offsets)
    var $cache_translations = NULL; // original -> translation mapping


    /* Methods */


    /**
     * Reads a 32bit Integer from the Stream
     *
     * @access private
     * @return Integer from the Stream
     */
    function readint() {
        if ($this->BYTEORDER == 0) {
            // low endian
            $low_end = unpack('V', $this->STREAM->read(4));
            return array_shift($low_end);
        } else {
            // big endian
            $big_end = unpack('N', $this->STREAM->read(4));
            return array_shift($big_end);
        }
    }

    /**
     * Reads an array of Integers from the Stream
     *
     * @param int count How many elements should be read
     * @return Array of Integers
     */
    function readintarray($count) {
    if ($this->BYTEORDER == 0) {
            // low endian
            return unpack('V'.$count, $this->STREAM->read(4 * $count));
        } else {
            // big endian
            return unpack('N'.$count, $this->STREAM->read(4 * $count));
        }
    }

    /**
     * Constructor
     *
     * @param object Reader the StreamReader object
     * @param boolean enable_cache Enable or disable caching of strings (default on)
     */
    function gettext_reader($Reader, $enable_cache = true) {
        // If there isn't a StreamReader, turn on short circuit mode.
        if (! $Reader || isset($Reader->error) ) {
            $this->short_circuit = true;
            return;
        }

        // Caching can be turned off
        $this->enable_cache = $enable_cache;

        // $MAGIC1 = (int)0x950412de; //bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565 [^]
        $MAGIC1 = (int) - 1794895138;
        // $MAGIC2 = (int)0xde120495; //bug
        $MAGIC2 = (int) - 569244523;
        // 64-bit fix
        $MAGIC3 = (int) 2500072158;

        $this->STREAM = $Reader;
        $magic = $this->readint();
        if ($magic == $MAGIC1 || $magic == $MAGIC3) { // to make sure it works for 64-bit platforms
            $this->BYTEORDER = 0;
        } elseif ($magic == ($MAGIC2 & 0xFFFFFFFF)) {
            $this->BYTEORDER = 1;
        } else {
            $this->error = 1; // not MO file
            return false;
        }

        // FIXME: Do we care about revision? We should.
        $revision = $this->readint();

        $this->total = $this->readint();
        $this->originals = $this->readint();
        $this->translations = $this->readint();
    }

    /**
     * Loads the translation tables from the MO file into the cache
     * If caching is enabled, also loads all strings into a cache
     * to speed up translation lookups
     *
     * @access private
     */
    function load_tables() {
        if (is_array($this->cache_translations) &&
            is_array($this->table_originals) &&
            is_array($this->table_translations))
            return;

        /* get original and translations tables */
        $this->STREAM->seekto($this->originals);
        $this->table_originals = $this->readintarray($this->total * 2);
        $this->STREAM->seekto($this->translations);
        $this->table_translations = $this->readintarray($this->total * 2);

        if ($this->enable_cache) {
            $this->cache_translations = array ();
            /* read all strings in the cache */
            for ($i = 0; $i < $this->total; $i++) {
                $this->STREAM->seekto($this->table_originals[$i * 2 + 2]);
                $original = $this->STREAM->read($this->table_originals[$i * 2 + 1]);
                $this->STREAM->seekto($this->table_translations[$i * 2 + 2]);
                $translation = $this->STREAM->read($this->table_translations[$i * 2 + 1]);
                $this->cache_translations[$original] = $translation;
            }
        }
    }

    /**
     * Returns a string from the "originals" table
     *
     * @access private
     * @param int num Offset number of original string
     * @return string Requested string if found, otherwise ''
     */
    function get_original_string($num) {
        $length = $this->table_originals[$num * 2 + 1];
        $offset = $this->table_originals[$num * 2 + 2];
        if (! $length)
            return '';
        $this->STREAM->seekto($offset);
        $data = $this->STREAM->read($length);
        return (string)$data;
    }

    /**
     * Returns a string from the "translations" table
     *
     * @access private
     * @param int num Offset number of original string
     * @return string Requested string if found, otherwise ''
     */
    function get_translation_string($num) {
        $length = $this->table_translations[$num * 2 + 1];
        $offset = $this->table_translations[$num * 2 + 2];
        if (! $length)
            return '';
        $this->STREAM->seekto($offset);
        $data = $this->STREAM->read($length);
        return (string)$data;
    }

    /**
     * Binary search for string
     *
     * @access private
     * @param string string
     * @param int start (internally used in recursive function)
     * @param int end (internally used in recursive function)
     * @return int string number (offset in originals table)
     */
    function find_string($string, $start = -1, $end = -1) {
        if (($start == -1) or ($end == -1)) {
            // find_string is called with only one parameter, set start end end
            $start = 0;
            $end = $this->total;
        }
        if (abs($start - $end) <= 1) {
            // We're done, now we either found the string, or it doesn't exist
            $txt = $this->get_original_string($start);
            if ($string == $txt)
                return $start;
            else
                return -1;
        } else if ($start > $end) {
            // start > end -> turn around and start over
            return $this->find_string($string, $end, $start);
        } else {
            // Divide table in two parts
            $half = (int)(($start + $end) / 2);
            $cmp = strcmp($string, $this->get_original_string($half));
            if ($cmp == 0)
                // string is exactly in the middle => return it
                return $half;
            else if ($cmp < 0)
                // The string is in the upper half
                return $this->find_string($string, $start, $half);
            else
                // The string is in the lower half
                return $this->find_string($string, $half, $end);
        }
    }

    /**
     * Translates a string
     *
     * @access public
     * @param string string to be translated
     * @return string translated string (or original, if not found)
     */
    function translate($string) {
        if ($this->short_circuit)
            return $string;
        $this->load_tables();

        if ($this->enable_cache) {
            // Caching enabled, get translated string from cache
            if (array_key_exists($string, $this->cache_translations))
                return $this->cache_translations[$string];
            else
                return $string;
        } else {
            // Caching not enabled, try to find string
            $num = $this->find_string($string);
            if ($num == -1)
                return $string;
            else
                return $this->get_translation_string($num);
        }
    }

    /**
     * Get possible plural forms from MO header
     *
     * @access private
     * @return string plural form header
     */
    function get_plural_forms() {
        // lets assume message number 0 is header
        // this is true, right?
        $this->load_tables();

        // cache header field for plural forms
        if (! is_string($this->pluralheader)) {
            if ($this->enable_cache) {
                $header = $this->cache_translations[""];
            } else {
                $header = $this->get_translation_string(0);
            }
            $header .= "\n"; //make sure our regex matches
            if (eregi("plural-forms: ([^\n]*)\n", $header, $regs))
                $expr = $regs[1];
            else
                $expr = "nplurals=2; plural=n == 1 ? 0 : 1;";

            // add parentheses
             // important since PHP's ternary evaluates from left to right
             $expr.= ';';
             $res= '';
             $p= 0;
             for ($i= 0; $i < strlen($expr); $i++) {
                $ch= $expr[$i];
                switch ($ch) {
                    case '?':
                        $res.= ' ? (';
                        $p++;
                        break;
                    case ':':
                        $res.= ') : (';
                        break;
                    case ';':
                        $res.= str_repeat( ')', $p) . ';';
                        $p= 0;
                        break;
                    default:
                        $res.= $ch;
                }
            }
            $this->pluralheader = $res;
        }

        return $this->pluralheader;
    }

    /**
     * Detects which plural form to take
     *
     * @access private
     * @param n count
     * @return int array index of the right plural form
     */
    function select_string($n) {
        if (is_null($this->select_string_function)) {
            $string = $this->get_plural_forms();
            if (preg_match("/nplurals\s*=\s*(\d+)\s*\;\s*plural\s*=\s*(.*?)\;+/", $string, $matches)) {
                $nplurals = $matches[1];
                $expression = $matches[2];
                $expression = str_replace("n", '$n', $expression);
            } else {
                $nplurals = 2;
                $expression = ' $n == 1 ? 0 : 1 ';
            }
            $func_body = "
                \$plural = ($expression);
                return (\$plural <= $nplurals)? \$plural : \$plural - 1;";
            $this->select_string_function = create_function('$n', $func_body);
        }
        return call_user_func($this->select_string_function, $n);
    }

    /**
     * Plural version of gettext
     *
     * @access public
     * @param string single
     * @param string plural
     * @param string number
     * @return translated plural form
     */
    function ngettext($single, $plural, $number) {
        if ($this->short_circuit) {
            if ($number != 1)
                return $plural;
            else
                return $single;
        }

        // find out the appropriate form
        $select = $this->select_string($number);

        // this should contains all strings separated by NULLs
        $key = $single.chr(0).$plural;


        if ($this->enable_cache) {
            if (! array_key_exists($key, $this->cache_translations)) {
                return ($number != 1) ? $plural : $single;
            } else {
                $result = $this->cache_translations[$key];
                $list = explode(chr(0), $result);
                return $list[$select];
            }
        } else {
            $num = $this->find_string($key);
            if ($num == -1) {
                return ($number != 1) ? $plural : $single;
            } else {
                $result = $this->get_translation_string($num);
                $list = explode(chr(0), $result);
                return $list[$select];
            }
        }
    }

}

?>
Attached Files

- Relationships

- Notes
(0003361)
foxcold
08-27-08 04:43

OutOfMemoryError:

for ($i = 0; $i < $this->total; $i++) {
                $this->STREAM->seekto($this->table_originals[$i * 2 + 2]);
                $original = $this->STREAM->read($this->table_originals[$i * 2 + 1]);
                $this->STREAM->seekto($this->table_translations[$i * 2 + 2]);
                $translation = $this->STREAM->read($this->table_translations[$i * 2 + 1]);
                $this->cache_translations[$original] = $translation;
            }
 
(0003364)
nam
08-28-08 06:54

Need complete reproducible test case. For memory errors, the JDK version, jvm-args, and OS would also be helpful. If not running Resin, then please run against your latest app server version.

By the way, Quercus comes with full 100% Java gettext support. MO, as well as human-readable PO, files are supported. Caching is per JVM (technically per Quercus instance).
 
(0003372)
foxcold
08-01-08 20:05

os : windows vista U
jdk : 1.5 and 1.6 any version
jvm -args : -Xms64m -Xmx512m to -Xms64m -Xmx1536m
app server : weblogic 10 any tomcat 6
quercus version: 3.1.6
php app :WordPress 2.6.1 and WordPress mu
 
(0003833)
lepe
02-22-09 20:22

I think this is related (and a Temporally solution):

http://forum.caucho.com/?q=node/261 [^]
 

- Issue History
Date Modified Username Field Change
08-27-08 04:40 foxcold New Issue
08-27-08 04:43 foxcold Note Added: 0003361
08-28-08 06:54 nam Note Added: 0003364
08-01-08 20:05 foxcold Note Added: 0003372
02-22-09 20:22 lepe Note Added: 0003833


Mantis 1.0.0rc3[^]
Copyright © 2000 - 2005 Mantis Group
38 total queries executed.
32 unique queries executed.
Powered by Mantis Bugtracker