[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