Source for file Protocol.inc

Documentation is available at Protocol.inc

  1. <?php /*-*- mode: php; tab-width:4 -*-*/
  2.  
  3.   /* java_Protocol.php -- PHP/Java Bridge protocol implementation
  4.  
  5.   Copyright (C) 2003-2007 Jost Boekemeier
  6.  
  7.   This file is part of the PHP/Java Bridge.
  8.  
  9.   The PHP/Java Bridge ("the library") is free software; you can
  10.   redistribute it and/or modify it under the terms of the GNU General
  11.   Public License as published by the Free Software Foundation; either
  12.   version 2, or (at your option) any later version.
  13.  
  14.   The library is distributed in the hope that it will be useful, but
  15.   WITHOUT ANY WARRANTY; without even the implied warranty of
  16.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.   General Public License for more details.
  18.  
  19.   You should have received a copy of the GNU General Public License
  20.   along with the PHP/Java Bridge; see the file COPYING.  If not, write to the
  21.   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  22.   02111-1307 USA.
  23.  
  24.   Linking this file statically or dynamically with other modules is
  25.   making a combined work based on this library.  Thus, the terms and
  26.   conditions of the GNU General Public License cover the whole
  27.   combination.
  28.  
  29.   As a special exception, the copyright holders of this library give you
  30.   permission to link this library with independent modules to produce an
  31.   executable, regardless of the license terms of these independent
  32.   modules, and to copy and distribute the resulting executable under
  33.   terms of your choice, provided that you also meet, for each linked
  34.   independent module, the terms and conditions of the license of that
  35.   module.  An independent module is a module which is not derived from
  36.   or based on this library.  If you modify this library, you may extend
  37.   this exception to your version of the library, but you are not
  38.   obligated to do so.  If you do not wish to do so, delete this
  39.   exception statement from your version. */
  40.  
  41. require_once ("${JAVA_BASE}/Options.inc");
  42. require_once ("${JAVA_BASE}/Client.inc");
  43.  
  44. /**
  45.  * @access private
  46.  */
  47. function java_getHeader($name$array{
  48.   if (array_key_exists($name$array)) return $array[$name];
  49.   $name="HTTP_$name"// apache uses HTTP_ prefix
  50.   if (array_key_exists($name$array)) return $array[$name];
  51.   return null;
  52. }
  53.  
  54. /**
  55.  * @access private
  56.  */
  57. class java_SocketChannel {
  58.   public $peer$protocol;
  59.   private $channelName$host;
  60.  
  61.   function java_SocketChannel($peer$protocol$host$channelName{
  62.     $this->peer $peer;
  63.     $this->protocol $protocol;
  64.     $this->host $host;
  65.     $this->channelName $channelName;
  66.   }
  67.   function fwrite($data{
  68.     return fwrite($this->peer$data);
  69.   }
  70.   function fread($size{
  71.     return fread($this->peer$size);
  72.   }
  73.   function getKeepAlive({
  74.     // keep alive, required by protocol
  75.     return "<F p=\"A\" />";
  76.   }
  77.   function keepAlive({
  78.     $this->fread(10)// <F p="A"/>
  79.   }
  80.   function shutdownBrokenConnection ({
  81.     fclose($this->peer);
  82.   
  83. }
  84. /**
  85.  * @access private
  86.  */
  87. class java_EmptyPipeChannel {
  88.   function open($handler{
  89.       if (false$handler $handler;
  90.     throw new java_RuntimeException("protocol error: socket channel names must not start with a slash");
  91.   }
  92.   function getName({
  93.     return null;
  94.   }
  95.   function getKeepAlive({return "";}
  96.   function keepAlive({}
  97.   function shutdownBrokenConnection ({}
  98. }
  99. /**
  100.  * @access private
  101.  */
  102. class java_PipeChannel extends java_EmptyPipeChannel {
  103.   public $peer$peerr$peerr_desc$name;
  104.   public $fifo$fifor;
  105.   public $iname$oname;
  106.  
  107.   function java_PipeChannel($name{
  108.     $this->name $name;
  109.     $this->iname $this->name ".i";
  110.     $mask umask(0);
  111.     $this->fifor posix_mkfifo($this->iname0666);
  112.     $this->oname $this->name ".o";
  113.     $this->fifo posix_mkfifo($this->oname0666);
  114.     umask($mask);
  115.   }
  116.   function open($handler{
  117.       if (false$handler $handler;
  118.       
  119.     $this->peerr fopen($this->iname"r");
  120.     $this->peerr_desc array($this->peerr);
  121.     stream_set_blocking($this->peerrfalse);
  122.     stream_set_timeout($this->peerr-1);
  123.  
  124.     $this->peer fopen($this->oname"w");
  125.     unlink($this->iname);
  126.     unlink($this->oname);
  127.     unlink($this->name);
  128.     stream_set_timeout($this->peer-1);
  129.     return $this;
  130.   }
  131.   function fwrite($data{
  132.       return fwrite($this->peer$data);
  133.   }
  134.   function fread($size{
  135.     static $empty NULL;
  136.     stream_select($this->peerr_desc$empty$empty1677216);
  137.     return fread($this->peerr$size);
  138.   }
  139.   function getName({
  140.     return $this->name;
  141.   }
  142.   // no need to fclose peer/peerr explicitly as PHP automatically closes 
  143.   // fopen'ed files in rshutdown.
  144. }
  145.  
  146. /**
  147.  * @access private
  148.  */
  149. class java_SocketHandler {
  150.   public $protocol$channel;
  151.  
  152.   function java_SocketHandler($protocol$channel{
  153.     $this->protocol $protocol;
  154.     $this->channel $channel;
  155.   }
  156.   function write($data{
  157.       return $this->channel->fwrite($data);
  158.   }
  159.   function read($size{
  160.     return $this->channel->fread($size);
  161.   }
  162.   function redirect({}
  163.   function getKeepAlive({
  164.     return $this->channel->getKeepAlive();
  165.   }
  166.   function keepAlive({
  167.     $this->channel->keepAlive();
  168.   }
  169.   function dieWithBrokenConnection($msg{
  170.     unset($this->protocol->client->protocol);
  171.     $error error_get_last();
  172.     die ("${msg} ".$error["message"]);
  173.   }
  174.   function shutdownBrokenConnection ($msg{
  175.     $this->channel->shutdownBrokenConnection();
  176.     $this->dieWithBrokenConnection($msg);
  177.   }
  178. }
  179. /**
  180.  * @access private
  181.  */
  182. class java_HttpHandler extends java_SocketHandler {
  183.   public $headers;
  184.   public $redirect;
  185.   
  186.   public $context$ssl$port// used by reopen
  187.   public $host// used when creating a socket channel lazily. the port# is passed via X_JAVABRIDGE_CHANNEL
  188.  
  189.   public $socket// we write to the socket directly and keep the pipe channel for later use
  190.   
  191.   function createPipeChannel($host$pipe_dir{
  192.     if($pipe_dir && ($host == "127.0.0.1" || (substr($host,0,9== "localhost")))
  193.       return new java_PipeChannel(tempnam($pipe_dir".php_java_bridge"));
  194.     return new java_EmptyPipeChannel();
  195.   }
  196.   function close({
  197.     fclose($this->socket);
  198.   }
  199.   function shutdownBrokenConnection ($msg{
  200.     $this->close();
  201.     $this->dieWithBrokenConnection($msg);
  202.   }
  203.   function open({
  204.       $errno null$errstr null;
  205.   /* Do not pfsockopen here, the J2EE server may not be able to handle
  206.     hundreds of persistent connections to the servlet very well */
  207.     $socket JAVA_PERSISTENT_SERVLET_CONNECTIONS 
  208.       pfsockopen("{$this->ssl}{$this->host}", $this->port$errno$errstr30:
  209.        fsockopen("{$this->ssl}{$this->host}", $this->port$errno$errstr30);
  210.  
  211.     if (!$socketthrow new java_ConnectException("Could not connect to the J2EE server {$this->ssl}{$this->host}:{$this->port}. Please start it, for example with the command: \"java -jar JavaBridge.jar SERVLET:8080 3 JavaBridge.log\" or, if the back end has been compiled to native code, with \"modules/java SERVLET:8080 3 JavaBridge.log\". Error message: $errstr ($errno)\n");
  212.     stream_set_timeout($socket, -1);
  213.     return $socket;
  214.   }
  215.   function java_HttpHandler($protocol, $ssl, $host, $port) {
  216.     $this->protocol $protocol;
  217.     $this->ssl $ssl;
  218.     $this->host $host;
  219.     $this->port $port;
  220.     $this->channel $this->createPipeChannel($host$protocol->client->RUNTIME['PIPE_DIR']);
  221.     $this->socket $this->open();
  222.   }
  223.   function getCookies() {
  224.     $str="";
  225.     $first=true;
  226.     foreach($_COOKIE as $k => $v) {
  227.       $str .= ($first ? "Cookie: $k=$v":"$k=$v");
  228.       $first=false;
  229.     }
  230.     if(!$first) $str .= "\r\n";
  231.     return $str;
  232.   }
  233.   function getContextFromCgiEnvironment() {
  234.     $ctx = java_getHeader('X_JAVABRIDGE_CONTEXT', $_SERVER);
  235.     return $ctx;
  236.   }
  237.   function getChannelName() {
  238.     $name = $this->channel->getName();
  239.     return !is_null($namesprintf("X_JAVABRIDGE_CHANNEL: %s\r\n"$namenull;
  240.   }
  241.   function getContext() {
  242.     $ctx = $this->getContextFromCgiEnvironment();
  243.     $context "";
  244.     if($ctx{
  245.       $context = sprintf("X_JAVABRIDGE_CONTEXT: %s\r\n", $ctx);
  246.     }
  247.     return $context;
  248.   }
  249.   function getWebAppInternal() {
  250.     // from createHttpHandler
  251.     $context = $this->protocol->webContext;
  252.     if(isset($context)) return $context;
  253.  
  254.     /* Coerce a http://xyz.com/kontext/foo.php request to the back
  255.        end: http://xyz.com:{java_hosts[0]}/kontext/foo.php.  For
  256.        example if we receive a request:
  257.        http://localhost/sessionSharing.php and java.servlet is On and
  258.        java.hosts is "127.0.0.1:8080" the code would connect to the
  259.        back end:
  260.        http://127.0.0.1:8080/sessionSharing.phpjavabridge. This
  261.        creates a cookie with PATH value "/".  If java_servlet is User
  262.        the request http://localhost/myContext/sessionSharing.php the
  263.        code would connect to
  264.        http://127.0.0.1/myContext/sessionSharing.phpjavabridge and a
  265.        cookie with a PATH value "/myContext" would be created.
  266.     */
  267.     return (JAVA_SERVLET == "User" &&
  268.             array_key_exists('PHP_SELF'$_SERVER&&
  269.             array_key_exists('HTTP_HOST'$_SERVER))
  270.       ? $_SERVER['PHP_SELF']."javabridge"
  271.       : null;
  272.   }
  273.   function getWebApp() {
  274.     $context = $this->getWebAppInternal();
  275.     if(is_null($context)) $context JAVA_SERVLET;
  276.     if(is_null($context|| $context[0]!="/"
  277.       $context "/JavaBridge/JavaBridge.phpjavabridge";
  278.     return $context;
  279.   }
  280.   function write($data) {
  281.  
  282.     $compatibility = $this->protocol->client->RUNTIME["PARSER"]=="NATIVE"
  283.       ? (0103-JAVA_PREFER_VALUES)
  284.       : (0100+JAVA_PREFER_VALUES);
  285.     if(is_int(JAVA_LOG_LEVEL)) {
  286.       $compatibility |= 128 | (7 & JAVA_LOG_LEVEL)<<2;
  287.     }
  288.     $compatibility = chr ($compatibility);
  289.  
  290.     $this->headers null;
  291.     $socket $this->socket;
  292.     $len strlen($data);
  293.     $webapp $this->getWebApp();
  294.     $cookies $this->getCookies();
  295.     $channel $this->getChannelName();
  296.     $context $this->getContext();
  297.     $redirect $this->redirect;
  298.     $res "PUT ";
  299.     $res .= $webapp;
  300.     $res .= JAVA_PERSISTENT_SERVLET_CONNECTIONS " HTTP/1.1\r\n" " HTTP/1.0\r\n"
  301.     $res .= "Host: localhost\r\n";
  302.     $res .= "Content-Length: "$res .= $len$res .= "\r\n";
  303.     $res .= $context;
  304.     $res .= $cookies;
  305.     $res .= $redirect;
  306.     if(!is_null($channel)) $res .= $channel;
  307.     $res .= "\r\n";
  308.     $res .= "\177";
  309.     $res .= $compatibility;
  310.     $res .= $data;
  311.     
  312.     $count fwrite($socket$resor $this->shutdownBrokenConnection("Broken connection handle");
  313.     fflush($socket)                or $this->shutdownBrokenConnection("Broken connection handle");
  314.     
  315.     return $count;
  316.   }
  317.   function doSetCookie($key, $val, $path) {
  318.     $path=trim($path);
  319.  
  320.     $webapp = $this->getWebAppInternal()if(!$webapp$path="/";
  321.     setcookie($key$val0$path);
  322.   }
  323.   function parseHeaders() {
  324.     $this->headers array();
  325.     while (($str trim(fgets($this->socketJAVA_RECV_SIZE)))) {
  326.       if($str[0]=='X') {
  327.         if(!strncasecmp("X_JAVABRIDGE_REDIRECT", $str, 21)) {
  328.           $this->headers["redirect"]=trim(substr($str22));
  329.         } else if(!strncasecmp("X_JAVABRIDGE_CONTEXT", $str, 20)) {
  330.           $this->headers["context"]=trim(substr($str21));
  331.         }
  332.       } else if($str[0]=='S') {    // Set-Cookie:
  333.         if(!strncasecmp("SET-COOKIE", $str, 10)) {
  334.           $str=substr($str, 12);
  335.           $ar = explode(";", $str);
  336.           $cookie = explode("=",$ar[0]);
  337.           $path = "";
  338.           if(isset($ar[1])) $p=explode("=", $ar[1]);
  339.           if(isset($p)) $path=$p[1];
  340.           $this->doSetCookie($cookie[0]$cookie[1]$path);
  341.         }
  342.       } else if($str[0]=='C') { // Content-Length
  343.         if(!strncasecmp("CONTENT-LENGTH", $str, 14)) {
  344.           $this->headers["content_length"]=trim(substr($str15));
  345.         } else if(!strncasecmp("CONNECTION", $str, 10)) {
  346.           $this->headers["connection"]=trim(substr($str11));
  347.         }
  348.       }
  349.     }
  350.   }
  351.   function read($size) {
  352.       if (false) $size = $size;
  353.       
  354.      if(is_null($this->headers)) $this->parseHeaders();
  355.     $data fread($this->socket$this->headers['content_length']);
  356.     return $data;
  357.   }
  358.  
  359.   function getChannel($channelName) {
  360.       $errstr = null; $errno = null;
  361.     if($channelName[0]=='/') return $this->channel->open($this);
  362.     $peer pfsockopen($this->host$channelName$errno$errstr30);
  363.     if (!$peerthrow new java_RuntimeException("Could not connect to the context server {$this->host}:{$channelName}. Error message: $errstr ($errno)\n");
  364.     stream_set_timeout($peer, -1);
  365.     return new java_SocketChannel($peer, $this->protocol$this->host$channelName);
  366.   }
  367.  
  368.   function redirect() {
  369.     if(!isset($this->headers["redirect"])) { // no redirect received: must continue to send PUT requests
  370.       throw new java_RuntimeException("no Pipe- or SocketContextServer available.");
  371.     }
  372.     if(!isset($this->protocol->socketHandler)) {
  373.       $hostVec = java_Protocol::getHost();
  374.       $this->host $hostVec[0];
  375.       $channelName $this->headers["redirect"];
  376.       $context $this->headers["context"];
  377.       $len strlen($context);
  378.       $len0 chr(0xFF);
  379.       $len1 chr($len&0xFF)$len>>=8;
  380.       $len2 chr($len&0xFF);
  381.       $this->protocol->socketHandler=new java_SocketHandler($this->protocol$this->getChannel($channelName));
  382.       $this->protocol->write("\177${len0}${len1}${len2}${context}");
  383.       $this->context sprintf("X_JAVABRIDGE_CONTEXT: %s\r\n"$context);
  384.     }
  385.  
  386.     // close persistent connection
  387.     if ((!JAVA_PERSISTENT_SERVLET_CONNECTIONS) || 
  388.         (array_key_exists("connection", $this->headers)&&
  389.          !strncasecmp("close"$this->headers["connection"],5)))
  390.       $this->close ();
  391.  
  392.     $this->protocol->handler $this->protocol->socketHandler;
  393.  
  394.     // short path for $this->protocol->flush(): avoid ContextRunner wait timeout
  395.     $this->protocol->handler->write($this->protocol->client->sendBuffer)
  396.         or $this->protocol->handler->shutdownBrokenConnection("Broken local connection handle");
  397.     $this->protocol->client->sendBuffer=null;
  398.  
  399.     // dummy: avoid ack delay
  400.     $this->protocol->handler->read(1)
  401.         or $this->protocol->handler->shutdownBrokenConnection("Broken local connection handle");
  402.   }
  403. }
  404.  
  405. /**
  406.  * @access private
  407.  */
  408. class java_Protocol {
  409.   public $client;
  410.   public $webContext;
  411.   public $serverName;
  412.  
  413.   function getOverrideHosts() {
  414.       if(array_key_exists('X_JAVABRIDGE_OVERRIDE_HOSTS', $_ENV)) {
  415.           $override = $_ENV['X_JAVABRIDGE_OVERRIDE_HOSTS'];
  416.           if(!is_null($override) && $override!='/') return $override;
  417.       }
  418.       // fcgi: override for redirect
  419.       return 
  420.         java_getHeader('X_JAVABRIDGE_OVERRIDE_HOSTS_REDIRECT', $_SERVER);
  421.   }
  422.   static function getHost() {
  423.     static $host;
  424.     if(!isset($host)) {
  425.       $hosts = explode(";", JAVA_HOSTS);
  426.       $host = explode(":", $hosts[0]); // TODO: check host list
  427.     }
  428.     return $host;
  429.   }
  430.   function createHttpHandler() {
  431.     $hostVec = java_Protocol::getHost();
  432.     $host = $hostVec[0];
  433.     $port = $hostVec[1];
  434.  
  435.     $overrideHosts = $this->getOverrideHosts();
  436.     $ssl "";
  437.     if($overrideHosts{
  438.       // handle "s:127.0.0.1:8080//JavaBridge/test.phpjavabridge" 
  439.       // or "s:127.0.0.1:8080" 
  440.       // or "/" 
  441.       // or ""
  442.      $s=$overrideHosts;
  443.      if((strlen($s)>2) && ($s[1]==':')) {
  444.        if($s[0]=='s')
  445.          $ssl="ssl://";
  446.        $s = substr($s, 2);
  447.      }
  448.      $webCtx = strpos($s, "//");
  449.      if($webCtx)
  450.        $host = substr($s, 0, $webCtx);
  451.      else
  452.        $host = $s;
  453.  
  454.      $idx = strpos($host, ':');
  455.      if($idx) {
  456.        if($webCtx)
  457.          $port = substr($host, $idx+1, $webCtx);
  458.        else
  459.          $port = substr($host, $idx+1);
  460.        $host = substr($host, 0, $idx);
  461.      } else {
  462.        $port = "8080";
  463.      }
  464.  
  465.      if($webCtx) $webCtx = substr($s, $webCtx+1);
  466.       $this->webContext $webCtx;
  467.     }
  468.     $this->serverName "$host:$port";
  469.     return new java_HttpHandler($this, $ssl, $host, $port);
  470.   }
  471.   /**
  472.    * connect to a local channel (no servlet engine or app server)
  473.    */
  474.   function createSimpleHandler($name) {
  475.     $channelName = $name;
  476.     if(!is_string($channelName)) {
  477.       $errno = null; $errstr = null;
  478.       $peer = pfsockopen($host="127.0.0.1", $channelName, $errno, $errstr, 30);
  479.     } else {
  480.       $type = $channelName[0];
  481.       if($type=='@' || $type=='/') {         // unix domain socket
  482.         if($type=='@') $channelName[0]="\0"; // abstract name space
  483.         $peer = pfsockopen($host="unix://${channelName}", null, $errno, $errstr, 30);
  484.         $channelName = null;
  485.       }
  486.       else {                    // tcp socket
  487.         list($host, $channelName) = explode(":", $channelName);
  488.         $peer = pfsockopen($host, $channelName, $errno, $errstr, 30);
  489.       }
  490.     }
  491.     if (!$peer) throw new java_ConnectException("Could not connect to the server $name. Error message: $errstr ($errno)\n");
  492.     stream_set_timeout($peer, -1);
  493.     $handler = new java_SocketHandler($this, new java_SocketChannel($peer, $this, $host, $channelName));
  494.  
  495.     $compatibility = $this->client->RUNTIME["PARSER"]=="NATIVE"
  496.       ? (0103-JAVA_PREFER_VALUES)
  497.       : (0100+JAVA_PREFER_VALUES);
  498.     
  499.     if(is_int(JAVA_LOG_LEVEL)) {
  500.       $compatibility |= 128 | (7 & JAVA_LOG_LEVEL)<<2;
  501.     }
  502.     $compatibility = chr ($compatibility);
  503.  
  504.     $this->write("\177$compatibility");
  505.     $this->serverName "127.0.0.1:$channelName";
  506.     return $handler;
  507.   }
  508.   function java_get_simple_channel() {
  509.     if (JAVA_HOSTS && (!JAVA_SERVLET || (JAVA_SERVLET == "Off")) && ($sel=JAVA_HOSTS) && ($sel[0]=='@' || ($sel[0]=='/'))) {
  510.       $hosts = explode(";", JAVA_HOSTS);
  511.       return $hosts[0];
  512.     }
  513.     return null;
  514.   }
  515.   function createHandler() {
  516.     if(!java_getHeader('X_JAVABRIDGE_OVERRIDE_HOSTS_REDIRECT', $_SERVER)&&
  517.        ((function_exists("java_get_default_channel")&&($defaultChannel=java_get_default_channel())) ||
  518.         ($defaultChannel=$this->java_get_simple_channel())) ) {
  519.       // if bind.c has started a local back end from Apache/IIS
  520.       return $this->createSimpleHandler($defaultChannel);
  521.     } else {
  522.       return $this->createHttpHandler();
  523.     }
  524.   }
  525.   function java_Protocol ($client) {
  526.     $this->client $client;
  527.     $this->handler $this->createHandler();
  528.   }
  529.  
  530.   function redirect() {
  531.     $this->handler->redirect();
  532.   }
  533.  
  534.   function read($size) {
  535.     return $this->handler->read($size);
  536.   }
  537.  
  538.   function sendData() {
  539.     $this->handler->write($this->client->sendBuffer);
  540.     $this->client->sendBuffer=null;
  541.   }
  542.   function flush() {
  543.     if(JAVA_DEBUG) {
  544.       echo "sending::: "; echo $this->client->sendBufferecho "\n";
  545.     }
  546.     $this->sendData();
  547.   }
  548.   function getKeepAlive() {
  549.     return $this->handler->getKeepAlive();
  550.   }
  551.   function keepAlive() {
  552.     $this->handler->keepAlive();
  553.   }
  554.   function handle() {
  555.     $this->client->handleRequests();
  556.   }
  557.   function write($data) {
  558.     $this->client->sendBuffer.=$data;
  559.   }
  560.   function finish() {
  561.     $this->flush();
  562.     $this->handle();
  563.     $this->redirect();
  564.   }
  565.   
  566.   function referenceBegin($name) {
  567.     $this->client->sendBuffer.=$this->client->preparedToSendBuffer;
  568.     if(JAVA_DEBUG{
  569.       echo "flushed preparedToSendBuffer: ".$this->client->preparedToSendBuffer."\n";
  570.     }
  571.     $this->client->preparedToSendBuffer=null;
  572.  
  573.     $signature=sprintf("<H p=\"1\" v=\"%s\">"$name);
  574.     $this->write($signature);
  575.     $signature[6]="2";
  576.     $this->client->currentArgumentsFormat $signature;
  577.   }
  578.   function referenceEnd() {
  579.     $this->client->currentArgumentsFormat.=$format="</H>";
  580.     $this->write($format);
  581.     $this->finish();
  582.     $this->client->currentCacheKey=null;
  583.   }
  584.   function createObjectBegin($name) {
  585.     $this->client->sendBuffer.=$this->client->preparedToSendBuffer;
  586.     if(JAVA_DEBUG{
  587.       echo "flushed preparedToSendBuffer: ".$this->client->preparedToSendBuffer."\n";
  588.     }
  589.     $this->client->preparedToSendBuffer=null;
  590.  
  591.     $signature=sprintf("<K p=\"1\" v=\"%s\">"$name);
  592.     $this->write($signature);
  593.     $signature[6]="2";
  594.     $this->client->currentArgumentsFormat $signature;
  595.   }
  596.   function createObjectEnd() {
  597.     $this->client->currentArgumentsFormat.=$format="</K>";
  598.     $this->write($format);
  599.     $this->finish();
  600.     $this->client->currentCacheKey=null;
  601.   }
  602.   function propertyAccessBegin($object, $method) {
  603.     $this->client->sendBuffer.=$this->client->preparedToSendBuffer;
  604.     if(JAVA_DEBUG{
  605.       echo "flushed preparedToSendBuffer: ".$this->client->preparedToSendBuffer."\n";
  606.     }
  607.     $this->client->preparedToSendBuffer=null;
  608.  
  609.     $this->write(sprintf("<G p=\"1\" v=\"%x\" m=\"%s\">"$object$method));
  610.     $this->client->currentArgumentsFormat="<G p=\"2\" v=\"%x\" m=\"${method}\">";
  611.   }
  612.   function propertyAccessEnd() {
  613.     $this->client->currentArgumentsFormat.=$format="</G>";
  614.     $this->write($format);
  615.     $this->finish();
  616.     $this->client->currentCacheKey=null;
  617.   }
  618.   function invokeBegin($object, $method) {
  619.     $this->client->sendBuffer.=$this->client->preparedToSendBuffer;
  620.     if(JAVA_DEBUG{
  621.       echo "flushed preparedToSendBuffer: ".$this->client->preparedToSendBuffer."\n";
  622.     }
  623.     $this->client->preparedToSendBuffer=null;
  624.  
  625.     $this->write(sprintf("<Y p=\"1\" v=\"%x\" m=\"%s\">"$object$method));
  626.     $this->client->currentArgumentsFormat="<Y p=\"2\" v=\"%x\" m=\"${method}\">";
  627.   }
  628.   function invokeEnd() {
  629.     $this->client->currentArgumentsFormat.=$format="</Y>";
  630.     $this->write($format);
  631.     $this->finish();
  632.     $this->client->currentCacheKey=null;
  633.   }
  634.   function resultBegin() {
  635.     $this->client->sendBuffer.=$this->client->preparedToSendBuffer;
  636.     if(JAVA_DEBUG{
  637.       echo "flushed preparedToSendBuffer: ".$this->client->preparedToSendBuffer."\n";
  638.     }
  639.     $this->client->preparedToSendBuffer=null;
  640.     
  641.     $this->write("<R>");
  642.   }
  643.   function resultEnd() {
  644.     $this->client->currentCacheKey=null;
  645.     $this->write("</R>");
  646.     $this->flush();
  647.   }
  648.   function writeString($name) {
  649.     $this->client->currentArgumentsFormat.=$format="<S v=\"%s\"/>";
  650.     $this->write(sprintf($formathtmlspecialchars($nameENT_COMPAT)));
  651.  
  652.   }
  653.   function writeBoolean($boolean) {
  654.     $this->client->currentArgumentsFormat.=$format="<T v=\"%s\"/>";
  655.     $this->write(sprintf($format$boolean));
  656.   }
  657.   function writeLong($l) {
  658.     $this->client->currentArgumentsFormat.="<J v=\"%d\"/>";
  659.     if($l<0{
  660.       $this->write(sprintf("<L v=\"%x\" p=\"A\"/>",-$l));
  661.     } else {
  662.       $this->write(sprintf("<L v=\"%x\" p=\"O\"/>",$l));
  663.     }
  664.   }
  665.   function writeULong($l) {
  666.     $this->client->currentArgumentsFormat.=$format="<L v=\"%x\" p=\"O\"/>";
  667.     $this->write(sprintf($format,$l));
  668.   }
  669.   function writeDouble($d) {
  670.     $this->client->currentArgumentsFormat.=$format="<D v=\"%.14e\"/>";
  671.     $this->write(sprintf($format$d));
  672.   }
  673.   function writeObject($object) {
  674.     $this->client->currentArgumentsFormat.=$format="<O v=\"%x\"/>";
  675.     $this->write(sprintf($format$object));
  676.   }
  677.  
  678.   /* the following routines are not cached */
  679.   function writeException($object, $str) {
  680.     $this->write(sprintf("<E v=\"%x\" m=\"%s\"/>",$objecthtmlspecialchars($strENT_COMPAT)));
  681.   }
  682.   function writeCompositeBegin_a() {
  683.     $this->write("<X t=\"A\">");
  684.   }
  685.   function writeCompositeBegin_h() {
  686.     $this->write("<X t=\"H\">");
  687.   }
  688.   function writeCompositeEnd() {
  689.     $this->write("</X>");
  690.   }
  691.   function writePairBegin_s($key) {
  692.     $this->write(sprintf("<P t=\"S\" v=\"%s\">"htmlspecialchars($keyENT_COMPAT)));
  693.   }
  694.   function writePairBegin_n($key) {
  695.     $this->write(sprintf("<P t=\"N\" v=\"%x\">",$key));
  696.   }
  697.   function writePairBegin() {
  698.     $this->write("<P>");
  699.   }
  700.   function writePairEnd() {
  701.     $this->write("</P>");
  702.   }
  703.   function writeUnref($object) {
  704.     $this->client->sendBuffer.=$this->client->preparedToSendBuffer;
  705.     //echo "clear prepared to send buffer\n";
  706.     $this->client->preparedToSendBuffer=null;
  707.     $this->write(sprintf("<U v=\"%x\"/>"$object));
  708.   }
  709.  
  710.   function getServerName() {
  711.     return $this->serverName;
  712.   }
  713. }

Documentation generated on Mon, 05 Jan 2009 21:11:03 +0100 by phpDocumentor 1.4.2