[sync] SyncML Server (RPC)

Anthony Mills amills at gascard.net
Mon Dec 8 12:38:39 PST 2003


Chuck,
I know I said I'd let you working on it, but I think I figured it out.  Here is
the patch and file.  It should get as far as returning a file with only
<SyncML></SyncML>.  It will also log the packets (both wbxml and xml) to
_debugDir, which will be extremely helpful.  If you like this and you check it
in, I think we can continue to develop the fun stuff, SyncML.

Thanks,

Anthony

PS  It only "compiles", I have not tested to see that it works.  I need to get
a server working again to test.

PPS You may need to change syncml_wbxml to different file name to get RPC to
pick it up.
-------------- next part --------------
<?php
/**
 * The Horde_RPC_syncml class provides a SyncML implementation of the Horde
 * RPC system.
 *
 * $Horde: framework/RPC/RPC/syncml.php,v 1.2 2003/11/27 00:27:06 jan Exp $
 *
 * Copyright 2003 Chuck Hagenbuch <chuck at horde.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Chuck Hagenbuch <chuck at horde.org>
 * @version $Revision: 1.2 $
 * @since   Horde 3.0
 * @package Horde_RPC
 */
 
 include_once 'syncml.php';
 
class Horde_RPC_syncml_wbxml extends Horde_RPC_syncml {

    function Horde_RPC_syncml_wbxml()
    {
        parent::Horde_RPC_syncml();
    }

    /**
     * Sends an RPC request to the server and returns the result.
     *
     * @param string    The raw request string.
     *
     * @return string   The XML encoded response from the server.
     */
    function getResponse($request)
    {
        //used for debugging
        static $packetNum = 0;
        
        //very useful for debugging
        if (isset($this->_debugDir)) {
            $f = fopen($this->_debugDir . 'syncml_client_' . $packetnum . '.wbxml', 'w');            
            fwrite($f, $request);            
            fclose($f);
        }
        
        $decode = new Decode();
        
        ob_start();        
        $decode->decode($request);        
        $ret = parent::getResponse(ob_get_clean());
        
        $encoder = new Encoder();
        
        ob_start();        
        $encoder.setOutput($ret2);
        $encoder.encode();
        
        //very useful for debugging
        if (isset($this->_debugDir)) {
            $f = fopen($this->_debugDir . 'syncml_server_' . $packetnum . '.wbxml', 'w');
            fwrite($f, $ret2);
            fclose($f);
        }
        
        return $ret2;
    }

    /**
     * Get the Content-Type of the response.
     *
     * @return string  The MIME Content-Type of the RPC response.
     */
    function getResponseContentType()
    {
        return 'application/vnd.syncml+wbxml';
    }

}
-------------- next part --------------
? patch.txt
? RPC/RPC/syncml_wbxml.php
Index: RPC/RPC/syncml.php
===================================================================
RCS file: /repository/framework/RPC/RPC/syncml.php,v
retrieving revision 1.2
diff -u -r1.2 syncml.php
--- RPC/RPC/syncml.php	27 Nov 2003 00:27:06 -0000	1.2
+++ RPC/RPC/syncml.php	8 Dec 2003 20:30:39 -0000
@@ -15,7 +15,11 @@
  * @since   Horde 3.0
  * @package Horde_RPC
  */
-class Horde_RPC_syncml extends Horde_RPC {
+ 
+ include_once 'Horde/RPC.php';
+ include_once 'XML/WBXML/ContentHandler.php';
+ 
+class Horde_RPC_syncml extends Horde_RPC { //extends XML_WBXML_ContentHandler {  
 
     /**
      * Resource handler for the RPC server.
@@ -24,6 +28,21 @@
     var $_server;
 
     /**
+     * Ouput ContentHandler used to output xml events.
+     * @var object $server
+     */
+    var $_output;
+    
+    /**
+     */
+    var $_xmlstack;
+    
+    /**
+     *  Debug directory, if set will output packets
+     */
+    var $_debugDir = "/tmp/";
+    
+    /**
      * SyncML server constructor
      *
      * @access private
@@ -43,8 +62,131 @@
      */
     function getResponse($request)
     {
+        //used for debugging
+        static $packetNum = 0;
+        
+        //very useful for debugging
+        if (isset($this->_debugDir)) {
+            $f = fopen($_debug . 'syncml_client_' . $packetnum . '.xml', 'w');
+            
+            fwrite($f, $request);
+            
+            fclose($f);
+        }
+        
+        //output can be set by a subclass, in that case we use it and don't return anything
+        if (!isset($_output)) {
+            $_output = &new XML_WBXML_ContentHandler();
+            ob_start();
+            _parse($request);
+            $ret = ob_get_contents();
+            ob_end_clean();
+            
+            //very useful for debugging
+            if (isset($this->_debugDir)) {
+                $f = fopen($_debug . 'syncml_server_' . $packetnum . '.xml', 'w');
+                fwrite($f, $ret);
+                fclose($f);
+            }
+            
+            return $ret;
+        } else {
+            //in case we need syncml_wbxml to use its own ContentHandler for opaque data
+            _parse($request);
+        }
+
+        //used for debugging
+        $packetNum++;
+    }
+    
+    function _parse($xml)
+    {
+        // Create the XML parser and set method references.
+        $this->_parser = xml_parser_create_ns($this->charset);
+        xml_set_object($this->_parser, $this);
+        xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
+        xml_set_element_handler($this->_parser, '_startElement', '_endElement');
+        xml_set_character_data_handler($this->_parser, '_characters');
+        xml_set_default_handler($this->_parser, 'defaultHandler');
+        xml_set_processing_instruction_handler($this->_parser, '');
+        xml_set_external_entity_ref_handler($this->_parser, '');
+
+        if (!xml_parse($this->_parser, $xml)) {
+            return $this->raiseError(sprintf('XML error: %s at line %d',
+                                             xml_error_string(xml_get_error_code($this->_parser)),
+                                             xml_get_current_line_number($this->_parser)));
+        }
+
+        xml_parser_free($this->_parser);
+    }
+    
+    function _startElement($parser, $tag, $attributes)
+    {
+        list($uri, $name) = $this->_splitURI($tag);
+
+        $this->_output->startElement($uri, $name, $attributes);
     }
 
+    function _characters($parser, $chars)
+    {
+        $this->_output->characters($chars);
+    }
+
+    function _endElement($parser, $tag)
+    {
+        list($uri, $name) = $this->_splitURI($tag);
+
+        $this->_output->endElement($uri, $name);
+    }
+    
+    function _splitURI($tag)
+    {
+        $parts = explode(':', $tag);
+        $name = array_pop($parts);
+        $uri = implode(':', $parts);
+        return array($uri, $name);
+    }
+
+    function startElement($uri, $element, $attrs)
+    {        
+        switch ($_xmlStack) 
+        {
+            case 0:
+                if ($element == 'SyncML') {
+                    $attrs = array();
+                    $this->_output->startElement($uri, 'SyncML', $attrs);
+                }
+                break;
+        }
+        
+        $_xmlStack++;
+    }
+
+    function endElement($uri, $element)
+    {
+        $_xmlStack--;
+        
+        switch ($_xmlStack) 
+        {
+            case 0:
+                if ($element == 'SyncML') {
+                    $attrs = array();
+                    $this->_output->endElement($uri, 'SyncML');
+                }
+                break;
+        }
+        
+        if (isset($this->_chars)) {
+            unset($this->_chars);
+        }
+    }
+
+    function characters($str)
+    {
+        if (isset($this->_chars))
+            $this->_chars = $this->_chars . $str;
+    }
+    
     /**
      * Get the Content-Type of the response.
      *
Index: XML_WBXML/WBXML/ContentHandler.php
===================================================================
RCS file: /repository/framework/XML_WBXML/WBXML/ContentHandler.php,v
retrieving revision 1.2
diff -u -r1.2 ContentHandler.php
--- XML_WBXML/WBXML/ContentHandler.php	7 Dec 2003 21:22:59 -0000	1.2
+++ XML_WBXML/WBXML/ContentHandler.php	8 Dec 2003 20:30:39 -0000
@@ -50,7 +50,7 @@
         $this->_indent++;
     }
 
-    function endElement($element)
+    function endElement($uri, $element)
     {
         $this->_indent--;
 
@@ -68,6 +68,7 @@
 
     function opaque($o)
     {
+        echo $o . "\n";
     }
 
     /**
Index: XML_WBXML/WBXML/Decoder.php
===================================================================
RCS file: /repository/framework/XML_WBXML/WBXML/Decoder.php,v
retrieving revision 1.10
diff -u -r1.10 Decoder.php
--- XML_WBXML/WBXML/Decoder.php	7 Dec 2003 21:22:59 -0000	1.10
+++ XML_WBXML/WBXML/Decoder.php	8 Dec 2003 20:30:39 -0000
@@ -355,7 +355,7 @@
             // right?
             $this->_tagStack[] = $tag;
         } else {
-            $this->_ch->endElement($tag);
+            $this->_ch->endElement($this->getCurrentURI(), $tag);
         }
     }
 
@@ -371,7 +371,7 @@
             $this->_isData = false;
         }
 
-        $this->_ch->endElement($tag);
+        $this->_ch->endElement($this->getCurrentURI(), $tag);
 
         return $tag;
     }


More information about the sync mailing list