diff --git a/phpgwapi/inc/horde/Horde/RPC.php b/phpgwapi/inc/horde/Horde/RPC.php
index ed0c56f5b5..0be53fa29b 100644
--- a/phpgwapi/inc/horde/Horde/RPC.php
+++ b/phpgwapi/inc/horde/Horde/RPC.php
@@ -7,22 +7,24 @@
* - Introspection documentation and method signatures.
*
* EXAMPLE:
+ *
* $response = Horde_RPC::request('xmlrpc',
- * '/horde/rpc.php', 'www.example.com', 80,
+ * 'http://localhost:80/horde/rpc.php'
* 'contacts.search',
* array(array('jan'), array('localsql'),
* array('name', 'email')),
- * Auth::getAuth(), Auth::getCredential('password'));
+ * array('user' => Auth::getAuth(),
+ * 'pass' => Auth::getCredential('password')));
+ *
*
- * $Horde: framework/RPC/RPC.php,v 1.7 2004/09/08 09:07:25 jan Exp $
+ * $Horde: framework/RPC/RPC.php,v 1.14 2006/01/01 21:10:10 jan Exp $
*
- * Copyright 2002-2004 Jan Schneider
+ * Copyright 2002-2006 Jan Schneider
*
* 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 Jan Schneider
- * @version $Revision$
* @since Horde 3.0
* @package Horde_RPC
*/
@@ -32,7 +34,7 @@ class Horde_RPC {
* Whether we need an authorized user or not.
*
* @access protected
- * @var boolean $_authorize.
+ * @var boolean
*/
var $_authorize = true;
@@ -113,9 +115,9 @@ class Horde_RPC {
/**
* Sends an RPC request to the server and returns the result.
*
- * @param string The raw request string.
+ * @param string The raw request string.
*
- * @return string The XML encoded response from the server.
+ * @return string The XML encoded response from the server.
*/
function getResponse($request)
{
@@ -137,14 +139,14 @@ class Horde_RPC {
*
* This statically called method is actually the RPC client.
*
- * @param string $driver The protocol driver to use. Currently 'soap' and
- * 'xmlrpc' are available.
+ * @param string $driver The protocol driver to use. Currently 'soap'
+ * and 'xmlrpc' are available.
* @param string $url The path to the RPC server on the called host.
* @param string $method The method to call.
- * @param array $params (optional) A hash containing any necessary
- * parameters for the method call.
- * @param $options Optional associative array of parameters depending on
- * the selected protocol driver.
+ * @param array $params A hash containing any necessary parameters for
+ * the method call.
+ * @param $options Associative array of parameters depending on
+ * the selected protocol driver.
*
* @return mixed The returned result from the method or a PEAR
* error object on failure.
@@ -177,21 +179,15 @@ class Horde_RPC {
* Attempts to return a concrete RPC server instance based on
* $driver.
*
- * @access public
+ * @param mixed $driver The type of concrete RPC subclass to return. If
+ * $driver is an array, then we will look in
+ * $driver[0]/lib/RPC/ for the subclass
+ * implementation named $driver[1].php.
+ * @param array $params A hash containing any additional configuration or
+ * connection parameters a subclass might need.
*
- * @param mixed $driver The type of concrete RPC subclass to
- * return. This is based on the protocol
- * driver ($driver). The code is dynamically
- * included. If $driver is an array, then
- * we will look in $driver[0]/lib/RPC/
- * for the subclass implementation named
- * $driver[1].php.
- * @param optional array $params A hash containing any additional
- * configuration or connection parameters
- * a subclass might need.
- *
- * @return object Horde_RPC The newly created concrete Horde_RPC server
- * instance, or a PEAR_Error on an error.
+ * @return Horde_RPC The newly created concrete Horde_RPC server instance,
+ * or a PEAR_Error on an error.
*/
function &factory($driver, $params = null)
{
@@ -210,11 +206,13 @@ class Horde_RPC {
}
$class = 'Horde_RPC_' . $driver;
if (class_exists($class)) {
- return $ret = &new $class($params);
+ $rpc = &new $class($params);
} else {
require_once 'PEAR.php';
- return PEAR::raiseError('Class definition of ' . $class . ' not found.');
+ $rpc = PEAR::raiseError('Class definition of ' . $class . ' not found.');
}
+
+ return $rpc;
}
/**
@@ -228,19 +226,12 @@ class Horde_RPC {
*
* This method must be invoked as: $var = &Horde_RPC::singleton()
*
- * @access public
+ * @param string $driver The type of concrete RPC subclass to return.
+ * @param array $params A hash containing any additional configuration or
+ * connection parameters a subclass might need.
*
- * @param string $driver The type of concrete RPC subclass to
- * return. This is based on the protocol
- * driver ($driver). The code is dynamically
- * included.
- * @param optional array $params A hash containing any additional
- * configuration or connection parameters a
- * subclass might need.
- *
- * @return object Horde_RPC The concrete Horde_RPC server reference, or a
- * PEAR_Error
- * on an error.
+ * @return Horde_RPC The concrete Horde_RPC server reference, or a
+ * PEAR_Error on an error.
*/
function &singleton($driver, $params = null)
{
diff --git a/phpgwapi/inc/horde/Horde/RPC/syncml.php b/phpgwapi/inc/horde/Horde/RPC/syncml.php
index 58689db194..db3921949c 100644
--- a/phpgwapi/inc/horde/Horde/RPC/syncml.php
+++ b/phpgwapi/inc/horde/Horde/RPC/syncml.php
@@ -1,25 +1,24 @@
, Anthony Mills
+ * Copyright 2003-2006 Chuck Hagenbuch
+ * Copyright 2003-2006 Anthony Mills
*
* 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
* @author Anthony Mills
- * @version $Revision$
* @since Horde 3.0
* @package Horde_RPC
*/
@@ -27,28 +26,33 @@ class Horde_RPC_syncml extends Horde_RPC {
/**
* Output ContentHandler used to output XML events.
- * @var object $_output
+ *
+ * @var object
*/
var $_output;
/**
- * @var integer $_xmlStack
+ * @var integer
*/
var $_xmlStack = 0;
/**
* Debug directory, if set will store copies of all packets.
+ *
+ * @var string
*/
- var $_debugDir = '/var/www/html/syncdebug/';
+ var $_debugDir = '/tmp/sync';
/**
* Default character set. Only supports UTF-8(ASCII?).
+ *
+ * @var string
*/
var $_charset = 'UTF-8';
/**
- * SyncML handles authentication internally, so bypass the RPC
- * framework auth check by just returning true here.
+ * SyncML handles authentication internally, so bypass the RPC framework
+ * auth check by just returning true here.
*/
function authorize()
{
@@ -60,80 +64,57 @@ class Horde_RPC_syncml extends Horde_RPC {
*
* @param string $request The raw request string.
*
- * @return string The XML encoded response from the server.
+ * @return string The XML encoded response from the server.
*/
function getResponse($request)
{
- // Catch any errors/warnings/notices that may get thrown while
- // processing. Don't want to let anything go to the client
- // that's not part of the valid response.
+ /* Catch any errors/warnings/notices that may get thrown while
+ * processing. Don't want to let anything go to the client that's not
+ * part of the valid response. */
ob_start();
- if(isset($GLOBALS['config_syncml']['syncml_debug_dir']))
- {
- $this->_debugDir = $GLOBALS['config_syncml']['syncml_debug_dir'];
- }
- // Very useful for debugging. Logs XML packets to
- // $this->_debugDir.
+ /* Very useful for debugging. Logs WBXML packets to
+ * $this->_debugDir. */
if (!empty($this->_debugDir) && is_dir($this->_debugDir)) {
- $today = date('Y-m-d');
- $deviceName = str_replace('/','',$_SERVER["HTTP_USER_AGENT"]);
- if(!is_dir($this->_debugDir .'/'. $today))
- {
- mkdir($this->_debugDir .'/'. $today);
- }
-
- $debugDir = $this->_debugDir .'/'. $today .'/'. $deviceName;
- if(!is_dir($debugDir))
- {
- mkdir($debugDir);
- }
-
- $packetNum = @intval(file_get_contents($debugDir . '/syncml.packetnum'));
+ $packetNum = @intval(file_get_contents($this->_debugDir . '/syncml.packetnum'));
if (!isset($packetNum)) {
$packetNum = 0;
}
- $f = @fopen($debugDir . '/syncml_client_' . $packetNum . '.xml', 'wb');
+ $f = @fopen($this->_debugDir . '/syncml_client_' . $packetNum . '.xml', 'wb');
if ($f) {
fwrite($f, $request);
fclose($f);
}
}
- // $this->_output can be already set by a subclass.
- // The subclass can use it's own ContentHandler and bypass
- // this classes use of the ContentHandler. In this case
- // no output is return from this method, instead the output
- // comes from the subclasses ContentHandler
- // We may need to add this code back when we get to the content
- //if (!isset($this->_output)) {
- include_once 'XML/WBXML/ContentHandler.php';
- $this->_output = &new XML_WBXML_ContentHandler();
- //}
+ require_once 'XML/WBXML/ContentHandler.php';
+ $this->_output = &new XML_WBXML_ContentHandler();
+
$this->_parse($request);
$response = $this->_output->getOutput();
- // Very useful for debugging.
+ /* Very useful for debugging. */
if (!empty($this->_debugDir) && is_dir($this->_debugDir)) {
- $f = @fopen($debugDir . '/syncml_server_' . $packetNum . '.xml', 'wb');
+ $f = @fopen($this->_debugDir . '/syncml_server_' . $packetNum . '.xml', 'wb');
if ($f) {
fwrite($f, $response);
fclose($f);
}
- $fp = @fopen($debugDir . '/syncml.packetnum', 'w');
+ $fp = @fopen($this->_debugDir . '/syncml.packetnum', 'w');
if ($fp) {
fwrite($fp, ++$packetNum);
fclose($fp);
}
}
- // Clear the output buffer that we started above, and log
- // anything that came up for later debugging.
+ /* Clear the output buffer that we started above, and log anything
+ * that came up for later debugging. */
$errorLogging = ob_get_clean();
if (!empty($errorLogging)) {
- Horde::logMessage($errorLogging, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ Horde::logMessage('SyncML: caught output=' .
+ $errorLogging, __FILE__, __LINE__, PEAR_LOG_DEBUG);
}
return $response;
@@ -141,7 +122,15 @@ class Horde_RPC_syncml extends Horde_RPC {
function _parse($xml)
{
- // Create the XML parser and set method references.
+ /* try to extract charset from XML text */
+ if(preg_match('/^\s*<\?xml[^>]*encoding\s*=\s*"([^"]*)"/i',
+ $xml, $m)) {
+ $this->_charset = $m[1];
+ }
+ NLS::setCharset($this->_charset);
+ String::setDefaultCharset($this->_charset);
+
+ /* 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);
@@ -187,7 +176,7 @@ class Horde_RPC_syncml extends Horde_RPC {
}
/**
- * Get the Content-Type of the response.
+ * Returns the Content-Type of the response.
*
* @return string The MIME Content-Type of the RPC response.
*/
@@ -198,7 +187,6 @@ class Horde_RPC_syncml extends Horde_RPC {
function startElement($uri, $element, $attrs)
{
-
$this->_xmlStack++;
switch ($this->_xmlStack) {
@@ -239,8 +227,8 @@ class Horde_RPC_syncml extends Horde_RPC {
case 2:
// Either or
if ($element == 'SyncHdr') {
- // Then we get the state from SyncMLHdr, and create a
- // new SyncMLBody.
+ // Then we get the state from SyncMLHdr, and create a new
+ // SyncMLBody.
$this->_contentHandler->endElement($uri, $element);
unset($this->_contentHandler);
diff --git a/phpgwapi/inc/horde/Horde/RPC/syncml_wbxml.php b/phpgwapi/inc/horde/Horde/RPC/syncml_wbxml.php
index 088ff193ce..1cf5920b17 100644
--- a/phpgwapi/inc/horde/Horde/RPC/syncml_wbxml.php
+++ b/phpgwapi/inc/horde/Horde/RPC/syncml_wbxml.php
@@ -1,23 +1,23 @@
, Anthony Mills
+ * Copyright 2003-2006 Chuck Hagenbuch
+ * Copyright 2003-2006 Anthony Mills
*
* 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
* @author Anthony Mills
- * @version $Revision$
* @since Horde 3.0
* @package Horde_RPC
*/
@@ -28,81 +28,75 @@ class Horde_RPC_syncml_wbxml extends Horde_RPC_syncml {
*
* @param string $request The raw request string.
*
- * @return string The WBXML encoded response from the server (binary).
+ * @return string The WBXML encoded response from the server (binary).
*/
function getResponse($request)
{
- // Catch any errors/warnings/notices that may get thrown while
- // processing. Don't want to let anything go to the client
- // that's not part of the valid response.
+ /* Catch any errors/warnings/notices that may get thrown while
+ * processing. Don't want to let anything go to the client that's not
+ * part of the valid response. */
ob_start();
- if(isset($GLOBALS['config_syncml']['syncml_debug_dir']))
- {
- $this->_debugDir = $GLOBALS['config_syncml']['syncml_debug_dir'];
- }
- // Very useful for debugging. Logs WBXML packets to
- // $this->_debugDir.
+ /* Very useful for debugging. Logs WBXML packets to
+ * $this->_debugDir. */
if (!empty($this->_debugDir) && is_dir($this->_debugDir)) {
- $today = date('Y-m-d');
- $deviceName = str_replace('/','',$_SERVER["HTTP_USER_AGENT"]);
- if(!is_dir($this->_debugDir .'/'. $today))
- {
- mkdir($this->_debugDir .'/'. $today);
- }
-
- $debugDir = $this->_debugDir .'/'. $today .'/'. $deviceName;
- if(!is_dir($debugDir))
- {
- mkdir($debugDir);
- }
-
- $packetNum = @intval(file_get_contents($debugDir . '/syncml_wbxml.packetnum'));
+ $packetNum = @intval(file_get_contents($this->_debugDir . '/syncml.packetnum'));
if (!isset($packetNum)) {
$packetNum = 0;
}
- $fp = fopen($debugDir . '/syncml_client_' . $packetNum . '.wbxml', 'wb');
+ $fp = fopen($this->_debugDir . '/syncml_client_' . $packetNum . '.wbxml', 'wb');
fwrite($fp, $request);
fclose($fp);
}
-
+
+
$decoder = &new XML_WBXML_Decoder();
- $xmlinput = $decoder->decode($request);
- if (is_a($xmlinput, 'PEAR_Error')) {
- return '';
+ $this->_output = &new XML_WBXML_Encoder();
+
+ $decoder->setContentHandler($this);
+
+ $r = $decoder->decode($request);
+ if (is_a($r, 'PEAR_Error')) {
+ Horde::logMessage('SyncML: ' .
+ $r->getMessage(), __FILE__, __LINE__, PEAR_LOG_ERR);
}
+ $this->_output->setVersion($decoder->getVersion());
+ $this->_output->setCharset($decoder->getCharsetStr());
+ $response = $this->_output->getOutput();
- $xmloutput = parent::getResponse($xmlinput);
-
- $encoder = &new XML_WBXML_Encoder();
- $encoder->setVersion($decoder->getVersion());
- $encoder->setCharset($decoder->getCharsetStr());
- $response = $encoder->encode($xmloutput);
+ if (is_a($response, 'PEAR_Error')) {
+ Horde::logMessage($response, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $response = $response->getMessage();
+ }
if (!empty($this->_debugDir) && is_dir($this->_debugDir)) {
- $fp = fopen($debugDir . '/syncml_server_' . $packetNum . '.wbxml', 'wb');
+ $fp = fopen($this->_debugDir . '/syncml_server_' . $packetNum . '.wbxml', 'wb');
fwrite($fp, $response);
fclose($fp);
- $fp = fopen($debugDir . '/syncml_wbxml.packetnum', 'w');
- fwrite($fp, ++$packetNum);
- fclose($fp);
+ $fp = @fopen($this->_debugDir . '/syncml.packetnum', 'w');
+ if ($fp) {
+ fwrite($fp, ++$packetNum);
+ fclose($fp);
+ }
+
}
- // Clear the output buffer that we started above, and log
- // anything that came up for later debugging.
+ /* Clear the output buffer that we started above, and log anything
+ * that came up for later debugging. */
$errorLogging = ob_get_clean();
if (!empty($errorLogging)) {
- Horde::logMessage($errorLogging, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ Horde::logMessage('SyncML: caught output=' . $errorLogging,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
}
return $response;
}
/**
- * Get the Content-Type of the response.
+ * Returns the Content-Type of the response.
*
* @return string The MIME Content-Type of the RPC response.
*/
diff --git a/phpgwapi/inc/horde/Horde/SyncML.php b/phpgwapi/inc/horde/Horde/SyncML.php
index 5083391bc3..2cf34a1483 100644
--- a/phpgwapi/inc/horde/Horde/SyncML.php
+++ b/phpgwapi/inc/horde/Horde/SyncML.php
@@ -477,7 +477,8 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
if ($element != 'Status' && $element != 'Map' && $element != 'Final') {
// We've got to do something! This can't be the last
// packet.
- $this->_actionCommands = true;
+ $this->_actionCommands = true;
+ Horde::logMessage("SyncML: found action commands <$element> " . $this->_actionCommands, __FILE__, __LINE__, PEAR_LOG_INFO);
}
switch($element)
@@ -490,6 +491,7 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
# break;
case 'Sync':
$state->setSyncStatus(CLIENT_SYNC_STARTED);
+ Horde::logMessage('SyncML: syncStatus(client sync started) ' . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_INFO);
break;
}
break;
@@ -567,11 +569,13 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
$this->_output->characters($this->_currentCmdID);
$this->_currentCmdID++;
$this->_output->endElement($state->getURI(), 'CmdID');
+
$this->_output->startElement($state->getURI(), 'Meta', $attrs);
- $this->_output->startElement($state->getURI(), 'Type', $attrs);
+ $this->_output->startElement($state->getURIMeta(), 'Type', $attrs);
$this->_output->characters('application/vnd.syncml-devinf+xml');
- $this->_output->endElement($state->getURI(), 'Type');
+ $this->_output->endElement($state->getURIMeta(), 'Type');
$this->_output->endElement($state->getURI(), 'Meta');
+
$this->_output->startElement($state->getURI(), 'Item', $attrs);
$this->_output->startElement($state->getURI(), 'Target', $attrs);
$this->_output->startElement($state->getURI(), 'LocURI', $attrs);
@@ -579,6 +583,7 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
$this->_output->endElement($state->getURI(), 'LocURI');
$this->_output->endElement($state->getURI(), 'Target');
$this->_output->endElement($state->getURI(), 'Item');
+
$this->_output->endElement($state->getURI(), 'Get');
}
}
@@ -590,6 +595,7 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
if($state->getSyncStatus() == CLIENT_SYNC_STARTED)
{
$state->setSyncStatus(CLIENT_SYNC_FINNISHED);
+ Horde::logMessage('SyncML: syncStatus(client sync finnished) ' . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_INFO);
}
$this->_clientSentFinal = true;
Horde::logMessage('SyncML: Sync _syncTag = '. $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_INFO);
diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php
index 7788c5a2e5..710110340a 100644
--- a/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php
+++ b/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php
@@ -4,44 +4,6 @@ include_once 'Horde/SyncML/State.php';
include_once 'Horde/SyncML/Command.php';
include_once 'Horde/SyncML/Command/Results.php';
-define('DEFAULT_DEFINF_10', '1.0The Horde Framework4711workstation./contactstext/x-vcard2.1text/x-vcard2.11234567./calendartext/x-vcalendar2.0text/x-vcalendar1.0text/x-vcalendar2.0text/x-vcalendar1.01234567text/x-vcalendarBEGINVCALENDARVEVENTVTODODTSTARTDTENDDTSTAMPSEQUENCEENDVCALENDARVEVENTVTODOUIDSUMMARYVERSION1.0AALARMCATEGORIESCLASSDALARMEXDATERESOURCESSTATUSATTACHATTENDEEDCREATEDCOMPLETEDDESCRIPTIONDUELAST-MODIFIEDLOCATIONPRIORITYRELATED-TORRULETRANSPURLtext/calendarBEGINVCALENDARVEVENTVTODOVALARMDTSTARTDTENDDTSTAMPSEQUENCEENDVCALENDARVEVENTVTODOVALARMUIDSUMMARYVERSION2.0CATEGORIESCLASSDALARMEXDATERESOURCESSTATUSATTACHATTENDEEDCREATEDCOMPLETEDDESCRIPTIONDUELAST-MODIFIEDLOCATIONPRIORITYRELATED-TOTRANSPURLRRULECOMMMENTACTIONTRIGGERDURATIONREPEATtext/x-vcardBEGINVCARDENDVCARDVERSION2.1ENCODINGVALUECHARSETFNNNAMENICKNAMEPHOTOBDAYADRLABELTELEMAILMAILERTZGEOTITLEROLELOGOAGENTORGCATEGORIESNOTEPRODIDREVSORT-STRINGSOUNDURLUIDCLASSKEY');
-define('DEFAULT_DEFINF_11', '1.1The Horde Framework4711workstation./contactstext/x-vcard2.1text/x-vcard2.11234567./calendartext/x-vcalendar2.0text/x-vcalendar1.0text/x-vcalendar2.0text/x-vcalendar1.01234567text/x-vcalendarBEGINVCALENDARVEVENTVTODODTSTARTDTENDDTSTAMPSEQUENCEENDVCALENDARVEVENTVTODOUIDSUMMARYVERSION1.0AALARMCATEGORIESCLASSDALARMEXDATERESOURCESSTATUSATTACHATTENDEEDCREATEDCOMPLETEDDESCRIPTIONDUELAST-MODIFIEDLOCATIONPRIORITYRELATED-TORRULETRANSPURLtext/calendarBEGINVCALENDARVEVENTVTODOVALARMDTSTARTDTENDDTSTAMPSEQUENCEENDVCALENDARVEVENTVTODOVALARMUIDSUMMARYVERSION2.0CATEGORIESCLASSDALARMEXDATERESOURCESSTATUSATTACHATTENDEEDCREATEDCOMPLETEDDESCRIPTIONDUELAST-MODIFIEDLOCATIONPRIORITYRELATED-TOTRANSPURLRRULECOMMMENTACTIONTRIGGERDURATIONREPEATtext/x-vcardBEGINVCARDENDVCARDVERSION2.1ENCODINGVALUECHARSETFNNNAMENICKNAMEPHOTOBDAYADRLABELTELEMAILMAILERTZGEOTITLEROLELOGOAGENTORGCATEGORIESNOTEPRODIDREVSORT-STRINGSOUNDURLUIDCLASSKEY');
-#define('DEFAULT_DEFINF', '1.0The Horde Framework4711'.
-#'workstationcontactstext/x-vcard2.1'.
-#'text/x-vcard2.1127'.
-#''.
-#
-#'calendartext/x-vcalendar2.0'.
-#'text/x-vcalendar1.0text/x-vcalendar2.0'.
-#'text/x-vcalendar1.017'.
-#
-#'text/x-vcalendarBEGINVCALENDARVEVENT'.
-#'VTODODTSTARTDTENDDTSTAMPSEQUENCE'.
-#'ENDVCALENDARVEVENTVTODOUID'.
-#'SUMMARYVERSION1.0AALARMCATEGORIES',
-#'CLASSDALARMEXDATERESOURCESSTATUS',
-#'ATTACHATTENDEEDCREATEDCOMPLETEDDESCRIPTION'.
-#'DUELAST-MODIFIEDLOCATIONPRIORITY'.
-#'RELATED-TORRULETRANSPURL'.
-#'text/calendarBEGINVCALENDARVEVENTVTODO'.
-#'VALARMDTSTARTDTENDDTSTAMPSEQUENCE'.
-#'ENDVCALENDARVEVENTVTODOVALARM'.
-#'UIDSUMMARYVERSION2.0CATEGORIES'.
-#'CLASSDALARMEXDATERESOURCESSTATUS'.
-#'ATTACHATTENDEEDCREATEDCOMPLETEDDESCRIPTION'.
-#'DUELAST-MODIFIEDLOCATIONPRIORITY'.
-#'RELATED-TOTRANSPURLRRULECOMMMENT'.
-#'ACTIONTRIGGERDURATIONREPEAT'.
-#
-#'text/x-vcardBEGINVCARDENDVCARD'.
-#'VERSION2.1ENCODINGVALUECHARSET'.
-#'FNNNAMENICKNAMEPHOTO'.
-#'BDAYADRLABELTELEMAIL'.
-#'MAILERTZGEOTITLEROLE'.
-#'LOGOAGENTORGCATEGORIESNOTE'.
-#'PRODIDREVSORT-STRINGSOUNDURL'.
-#'UIDCLASSKEY');
-
/**
* The Horde_SyncML_Command_Get class.
*
@@ -70,32 +32,151 @@ class Horde_SyncML_Command_Get extends Horde_SyncML_Command {
$status->setCmdRef($this->_cmdID);
$status->setTargetRef($ref);
$currentCmdID = $status->output($currentCmdID, $output);
- Horde::logMessage('SyncML: end output ref: '.$ref, __FILE__, __LINE__, PEAR_LOG_DEBUG);
- // Currently DEVINF seems to be ok only for SyncML 1.0. But
- // this is used by P800/P900 and these seem to require it:
- if ($state->isAuthorized() && $state->getVersion() == 0) {
- $results = &new Horde_SyncML_Command_Results();
- $results->setCmdRef($this->_cmdID);
- $results->setType("application/vnd.syncml-devinf+xml");
- $results->setlocSourceURI($ref);
- $results->setData(DEFAULT_DEFINF_10);
+ if ($state->isAuthorized()) {
+ $attrs = array();
+ $output->startElement($state->getURI(), 'Results', $attrs);
- $currentCmdID = $results->output($currentCmdID, $output);
- }
- elseif($state->isAuthorized() && $state->getVersion() == 1)
- {
- $results = &new Horde_SyncML_Command_Results();
- $results->setCmdRef($this->_cmdID);
- $results->setType("application/vnd.syncml-devinf+xml");
- $results->setlocSourceURI($ref);
- $results->setData(DEFAULT_DEFINF_11);
+ $output->startElement($state->getURI(), 'CmdID', $attrs);
+ $chars = $currentCmdID;
+ $output->characters($chars);
+ $output->endElement($state->getURI(), 'CmdID');
- $currentCmdID = $results->output($currentCmdID, $output);
-
+ $output->startElement($state->getURI(), 'MsgRef', $attrs);
+ $chars = $state->getMsgID();
+ $output->characters($chars);
+ $output->endElement($state->getURI(), 'MsgRef');
+
+ $output->startElement($state->getURI(), 'CmdRef', $attrs);
+ $chars = $this->_cmdID;
+ $output->characters($chars);
+ $output->endElement($state->getURI(), 'CmdRef');
+
+ $output->startElement($state->getURI(), 'Meta', $attrs);
+ $output->startElement($state->getURIMeta(), 'Type', $attrs);
+ if (is_a($output, 'XML_WBXML_Encoder')) {
+ $output->characters(MIME_SYNCML_DEVICE_INFO_WBXML);
+ } else {
+ $output->characters(MIME_SYNCML_DEVICE_INFO_XML);
+ }
+
+ $output->endElement($state->getURIMeta(), 'Type');
+ $output->endElement($state->getURI(), 'Meta');
+
+ $output->startElement($state->getURI(), 'Item', $attrs);
+ $output->startElement($state->getURI(), 'Source', $attrs);
+ $output->startElement($state->getURI(), 'LocURI', $attrs);
+ $output->characters($ref);
+ $output->endElement($state->getURI(), 'LocURI');
+ $output->endElement($state->getURI(), 'Source');
+
+ $output->startElement($state->getURI(), 'Data', $attrs);
+
+ $output->startElement($state->getURIDevInf() , 'DevInf', $attrs);
+ $output->startElement($state->getURIDevInf() , 'VerDTD', $attrs);
+ $output->characters(($state->getVersion() == 0) ? '1.0' : '1.1');
+ $output->endElement($state->getURIDevInf() , 'VerDTD', $attrs);
+ $output->startElement($state->getURIDevInf() , 'Man', $attrs);
+ $output->characters('www.egroupware.org');
+ $output->endElement($state->getURIDevInf() , 'Man', $attrs);
+ $output->startElement($state->getURIDevInf() , 'DevID', $attrs);
+ $output->characters($_SERVER['HTTP_HOST']);
+ $output->endElement($state->getURIDevInf() , 'DevID', $attrs);
+ $output->startElement($state->getURIDevInf() , 'DevTyp', $attrs);
+ $output->characters('server');
+ $output->endElement($state->getURIDevInf() , 'DevTyp', $attrs);
+ $this->_writeDataStore('notes', 'text/x-vnote', '1.1', $output,
+ array('text/plain' => '1.0'));
+ $this->_writeDataStore('contacts', 'text/x-vcard', '2.1', $output);
+ $this->_writeDataStore('tasks', 'text/x-vcalendar', '1.0', $output);
+ $this->_writeDataStore('calendar', 'text/x-vcalendar', '1.0', $output);
+ $output->endElement($state->getURIDevInf() , 'DevInf', $attrs);
+
+ $output->endElement($state->getURI(), 'Data');
+ $output->endElement($state->getURI(), 'Item');
+ $output->endElement($state->getURI(), 'Results');
+
+ $currentCmdID++;
}
return $currentCmdID;
}
+ /**
+ * Writes DevInf data for one DataStore.
+ *
+ * @param string $sourceref: data for SourceRef element.
+ * @param string $mimetype: data for <(R|T)x-Pref><CTType>
+ * @param string $version: data for <(R|T)x-Pref><VerCT>
+ * @param string &$output contenthandler that will received the output.
+ * @param array $additionaltypes: array of additional types for Tx and Rx;
+ * format array('text/vcard' => '2.0')
+ */
+ function _writeDataStore($sourceref, $mimetype, $version, &$output,
+ $additionaltypes = false)
+ {
+ $attrs = array();
+
+ $state = &$_SESSION['SyncML.state'];
+
+ $output->startElement($state->getURIDevInf() , 'DataStore', $attrs);
+ $output->startElement($state->getURIDevInf() , 'SourceRef', $attrs);
+ $output->characters($sourceref);
+ $output->endElement($state->getURIDevInf() , 'SourceRef', $attrs);
+
+ $output->startElement($state->getURIDevInf() , 'Rx-Pref', $attrs);
+ $output->startElement($state->getURIDevInf() , 'CTType', $attrs);
+ $output->characters($mimetype);
+ $output->endElement($state->getURIDevInf() , 'CTType', $attrs);
+ $output->startElement($state->getURIDevInf() , 'VerCT', $attrs);
+ $output->characters($version);
+ $output->endElement($state->getURIDevInf() , 'VerCT', $attrs);
+ $output->endElement($state->getURIDevInf() , 'Rx-Pref', $attrs);
+
+ if (is_array($additionaltypes)) {
+ foreach ($additionaltypes as $ct => $ctver){
+ $output->startElement($state->getURIDevInf() , 'Rx', $attrs);
+ $output->startElement($state->getURIDevInf() , 'CTType', $attrs);
+ $output->characters($ct);
+ $output->endElement($state->getURIDevInf() , 'CTType', $attrs);
+ $output->startElement($state->getURIDevInf() , 'VerCT', $attrs);
+ $output->characters($ctver);
+ $output->endElement($state->getURIDevInf() , 'VerCT', $attrs);
+ $output->endElement($state->getURIDevInf() , 'Rx', $attrs);
+ }
+ }
+
+ $output->startElement($state->getURIDevInf() , 'Tx-Pref', $attrs);
+ $output->startElement($state->getURIDevInf() , 'CTType', $attrs);
+ $output->characters($mimetype);
+ $output->endElement($state->getURIDevInf() , 'CTType', $attrs);
+ $output->startElement($state->getURIDevInf() , 'VerCT', $attrs);
+ $output->characters($version);
+ $output->endElement($state->getURIDevInf() , 'VerCT', $attrs);
+ $output->endElement($state->getURIDevInf() , 'Tx-Pref', $attrs);
+
+ if (is_array($additionaltypes)) {
+ foreach ($additionaltypes as $ct => $ctver){
+ $output->startElement($state->getURIDevInf() , 'Tx', $attrs);
+ $output->startElement($state->getURIDevInf() , 'CTType', $attrs);
+ $output->characters($ct);
+ $output->endElement($state->getURIDevInf() , 'CTType', $attrs);
+ $output->startElement($state->getURIDevInf() , 'VerCT', $attrs);
+ $output->characters($ctver);
+ $output->endElement($state->getURIDevInf() , 'VerCT', $attrs);
+ $output->endElement($state->getURIDevInf() , 'Tx', $attrs);
+ }
+ }
+
+ $output->startElement($state->getURIDevInf() , 'SyncCap', $attrs);
+ $output->startElement($state->getURIDevInf() , 'SyncType', $attrs);
+ $output->characters('1');
+ $output->endElement($state->getURIDevInf() , 'SyncType', $attrs);
+ $output->startElement($state->getURIDevInf() , 'SyncType', $attrs);
+ $output->characters('2');
+ $output->endElement($state->getURIDevInf() , 'SyncType', $attrs);
+ $output->endElement($state->getURIDevInf() , 'SyncCap', $attrs);
+ $output->endElement($state->getURIDevInf() , 'DataStore', $attrs);
+ }
+
}
diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Status.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Status.php
index 41410bedb0..c3abf081fb 100644
--- a/phpgwapi/inc/horde/Horde/SyncML/Command/Status.php
+++ b/phpgwapi/inc/horde/Horde/SyncML/Command/Status.php
@@ -143,8 +143,8 @@ class Horde_SyncML_Command_Status extends Horde_SyncML_Command {
$output->startElement($state->getURI(), 'Item', $attrs);
$output->startElement($state->getURI(), 'Data', $attrs);
- // $metainfuri = $state->getURIMeta();
- $metainfuri = $state->getURI(); // debug by FOU
+ $metainfuri = $state->getURIMeta();
+ // $metainfuri = $state->getURI(); // debug by FOU
$output->startElement($metainfuri, 'Anchor', $attrs);
diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync.php
index 5e785730d8..2f294a91e2 100644
--- a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync.php
+++ b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync.php
@@ -142,23 +142,14 @@ class Horde_SyncML_Command_Sync extends Horde_Syncml_Command {
break;
}
- #Horde::logMessage('SyncML: ending sync to client '.$targets[0], __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ #
// no syncs left
if($state->getTargets() === FALSE)
$state->setSyncStatus(SERVER_SYNC_FINNISHED);
+ Horde::logMessage('SyncML: syncStatus(server_sync_finnished) '. $state->getSyncStatus, __FILE__, __LINE__, PEAR_LOG_DEBUG);
#############################
}
-# elseif($state->getSyncStatus() == CLIENT_SYNC_STARTED)
-# {
-# Horde::logMessage('SyncML: client alert '.$state->_currentSourceURI, __FILE__, __LINE__, PEAR_LOG_DEBUG);
-# Horde::logMessage('SyncML: client alert '.$state->_currentTargetURI, __FILE__, __LINE__, PEAR_LOG_DEBUG);
-# Horde::logMessage('SyncML: client alert '.$state->_currentTargetURIParameters, __FILE__, __LINE__, PEAR_LOG_DEBUG);
-# $alert = &new Horde_SyncML_Command_Alert(ALERT_NEXT_MESSAGE);
-# $alert->setSourceLocURI($state->_currentSourceURI);
-# $alert->setTargetLocURI((isset($state->_currentTargetURIParameters) ? $state->_currentTargetURI.'?/'.$state->_currentTargetURIParameters : $state->_currentTargetURI));
-# $currentCmdID = $alert->output($currentCmdID, $output);
-# }
return $currentCmdID;
}
diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/ContentSyncElement.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/ContentSyncElement.php
index 3723015038..e45da9fd85 100644
--- a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/ContentSyncElement.php
+++ b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/ContentSyncElement.php
@@ -127,7 +127,8 @@ class Horde_SyncML_Command_Sync_ContentSyncElement extends Horde_SyncML_Command_
}
if (isset($this->_content)) {
$output->startElement($state->getURI(), 'Data', $attrs);
- $chars = '_content.']]>';
+ #$chars = '_content.']]>';
+ $chars = $this->_content;
$output->characters($chars);
$output->endElement($state->getURI(), 'Data');
}
diff --git a/phpgwapi/inc/horde/Horde/SyncML/State.php b/phpgwapi/inc/horde/Horde/SyncML/State.php
index f985faa069..b4a888cd6b 100644
--- a/phpgwapi/inc/horde/Horde/SyncML/State.php
+++ b/phpgwapi/inc/horde/Horde/SyncML/State.php
@@ -289,6 +289,16 @@ class Horde_SyncML_State {
{
return $this->_msgID;
}
+
+ function setWBXML($wbxml)
+ {
+ $this->_wbxml = $wbxml;
+ }
+
+ function isWBXML()
+ {
+ return !empty($this->_wbxml);
+ }
function &getSyncStatus()
{
@@ -370,9 +380,11 @@ class Horde_SyncML_State {
if ($version == 0) {
$this->_uri = NAME_SPACE_URI_SYNCML;
$this->_uriMeta = NAME_SPACE_URI_METINF;
+ $this->_uriDevInf = NAME_SPACE_URI_DEVINF;
} else {
$this->_uri = NAME_SPACE_URI_SYNCML_1_1;
$this->_uriMeta = NAME_SPACE_URI_METINF_1_1;
+ $this->_uriDevInf = NAME_SPACE_URI_DEVINF_1_1;
}
}
@@ -408,7 +420,7 @@ class Horde_SyncML_State {
// store sessionID in a variable, because ->verify maybe resets that value
$sessionID = session_id();
if(!$GLOBALS['phpgw']->session->verify($sessionID, 'staticsyncmlkp3'))
- Horde::logMessage('SyncML_EGW: egw session('.$sessionID.') not verified ' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ Horde::logMessage('SyncML_EGW: egw session('.$sessionID. ') not verified ' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
}
return $this->_isAuthorized;
@@ -448,14 +460,28 @@ class Horde_SyncML_State {
function getURI()
{
- return $this->_uri;
+ /*
+ * The non WBXML devices (notably P900 and Sync4j seem to get confused
+ * by a element. They require
+ * just . So don't use an ns for non wbxml devices.
+ */
+# if ($this->isWBXML()) {
+ return $this->_uri;
+# } else {
+# return '';
+# }
}
-
function getURIMeta()
{
return $this->_uriMeta;
}
+ function getURIDevInf()
+ {
+ return $this->_uriDevInf;
+ }
+
+
/**
* Converts a Horde GUID (like
* kronolith:0d1b415fc124d3427722e95f0e926b75) to a client ID as
diff --git a/phpgwapi/inc/horde/XML/WBXML.php b/phpgwapi/inc/horde/XML/WBXML.php
index 8ead275272..382d0bb18b 100644
--- a/phpgwapi/inc/horde/XML/WBXML.php
+++ b/phpgwapi/inc/horde/XML/WBXML.php
@@ -63,12 +63,12 @@ define('CHARSET_UTF_16LE', 'UTF-16LE');
define('CHARSET_UTF_16', 'UTF-16');
/**
- * Copyright 2003-2005 Anthony Mills
+ * Copyright 2003-2006 Anthony Mills
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
*
- * $Horde: framework/XML_WBXML/WBXML.php,v 1.14 2005/01/03 13:09:24 jan Exp $
+ * $Horde: framework/XML_WBXML/WBXML.php,v 1.18 2006/01/01 21:10:25 jan Exp $
*
* @package XML_WBXML
*/
@@ -104,35 +104,25 @@ class XML_WBXML {
$bytes3 = 128 | XML_WBXML::getBits(3, $i);
$bytes4 = 128 | XML_WBXML::getBits(4, $i);
- $out .= chr($bytes4);
- $out .= chr($bytes3);
- $out .= chr($bytes2);
- $out .= chr($bytes1);
- $out .= chr($bytes0);
+ $out .= chr($bytes4) . chr($bytes3) . chr($bytes2) . chr($bytes1) . chr($bytes0);
} elseif ($i > 2097151) {
$bytes0 = 0 | XML_WBXML::getBits(0, $i);
$bytes1 = 128 | XML_WBXML::getBits(1, $i);
$bytes2 = 128 | XML_WBXML::getBits(2, $i);
$bytes3 = 128 | XML_WBXML::getBits(3, $i);
- $out .= chr($bytes3);
- $out .= chr($bytes2);
- $out .= chr($bytes1);
- $out .= chr($bytes0);
+ $out .= chr($bytes3) . chr($bytes2) . chr($bytes1) . chr($bytes0);
} elseif ($i > 16383) {
$bytes0 = 0 | XML_WBXML::getBits(0, $i);
$bytes1 = 128 | XML_WBXML::getBits(1, $i);
$bytes2 = 128 | XML_WBXML::getBits(2, $i);
- $out .= chr($bytes2);
- $out .= chr($bytes1);
- $out .= chr($bytes0);
+ $out .= chr($bytes2) . chr($bytes1) . chr($bytes0);
} elseif ($i > 127) {
$bytes0 = 0 | XML_WBXML::getBits(0, $i);
$bytes1 = 128 | XML_WBXML::getBits(1, $i);
- $out .= chr($bytes1);
- $out .= chr($bytes0);
+ $out .= chr($bytes1) . chr($bytes0);
} else {
$bytes0 = 0 | XML_WBXML::getBits(0, $i);
@@ -166,7 +156,6 @@ class XML_WBXML {
{
/**
* ADD CHAPTER
- * @var array $_DPIString
*/
$DPIString = array(2 => DPI_DTD_WML_1_0,
3 => DPI_DTD_WTA_1_0,
@@ -184,9 +173,9 @@ class XML_WBXML {
// Not all SyncML clients know this, so we
// should use the string table.
// 0xFD1 => DPI_DTD_SYNCML_1_1,
- // 0xFD2 => DPI_DTD_DEVINF_1_1,
+ 4051 => DPI_DTD_SYNCML_1_1,
+ 4052 => DPI_DTD_DEVINF_1_1,
);
-
return isset($DPIString[$i]) ? $DPIString[$i] : null;
}
@@ -194,7 +183,6 @@ class XML_WBXML {
{
/**
* ADD CHAPTER
- * @var array $_DPIInt
*/
$DPIInt = array(DPI_DTD_WML_1_0 => 2,
DPI_DTD_WTA_1_0 => 3,
@@ -228,7 +216,6 @@ class XML_WBXML {
{
/**
* From http://www.iana.org/assignments/character-sets
- * @var array $_charsetString
*/
$charsetString = array(3 => 'US-ASCII',
4 => 'ISO-8859-1',
@@ -252,7 +239,6 @@ class XML_WBXML {
{
/**
* From http://www.iana.org/assignments/character-sets
- * @var array $_charsetInt
*/
$charsetInt = array('US-ASCII' => 3,
'ISO-8859-1' => 4,
diff --git a/phpgwapi/inc/horde/XML/WBXML/ContentHandler.php b/phpgwapi/inc/horde/XML/WBXML/ContentHandler.php
index 7ee64da239..86337cd9b1 100644
--- a/phpgwapi/inc/horde/XML/WBXML/ContentHandler.php
+++ b/phpgwapi/inc/horde/XML/WBXML/ContentHandler.php
@@ -1,8 +1,8 @@
+ * Copyright 2003-2006 Anthony Mills
*
* See the enclosed file COPYING for license information (LGPL). If you did
* not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
@@ -33,7 +33,6 @@ class XML_WBXML_ContentHandler {
function XML_WBXML_ContentHandler()
{
$this->_currentUri = &new XML_WBXML_LifoQueue();
- $this->_output = '';
}
function raiseError($error)
@@ -67,13 +66,18 @@ class XML_WBXML_ContentHandler {
return $this->_output;
}
+ function getOutputSize()
+ {
+ return strlen($this->_output);
+ }
+
function startElement($uri, $element, $attrs)
{
$this->_output .= '<' . $element;
$currentUri = $this->_currentUri->top();
- if ((!$currentUri) || ($currentUri != $uri)) {
+ if (((!$currentUri) || ($currentUri != $uri)) && $uri) {
$this->_output .= ' xmlns="' . $uri . '"';
}
@@ -130,7 +134,7 @@ class XML_WBXML_LifoQueue {
function push($obj)
{
- array_push($this->_queue, $obj);
+ $this->_queue[] = $obj;
}
function pop()
diff --git a/phpgwapi/inc/horde/XML/WBXML/DTD.php b/phpgwapi/inc/horde/XML/WBXML/DTD.php
index e9f6bddccf..880c3dec00 100644
--- a/phpgwapi/inc/horde/XML/WBXML/DTD.php
+++ b/phpgwapi/inc/horde/XML/WBXML/DTD.php
@@ -1,11 +1,11 @@
+ * Copyright 2003-2006 Anthony Mills
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncML.php b/phpgwapi/inc/horde/XML/WBXML/DTD/SyncML.php
index 1b3c8e22f8..6f2edfa703 100644
--- a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncML.php
+++ b/phpgwapi/inc/horde/XML/WBXML/DTD/SyncML.php
@@ -3,12 +3,12 @@
include_once 'XML/WBXML/DTD.php';
/**
- * $Horde: framework/XML_WBXML/WBXML/DTD/SyncML.php,v 1.7 2005/01/03 13:09:25 jan Exp $
+ * $Horde: framework/XML_WBXML/WBXML/DTD/SyncML.php,v 1.11 2006/01/01 21:10:26 jan Exp $
*
* From Binary XML Content Format Specification Version 1.3, 25 July 2001
* found at http://www.wapforum.org
*
- * Copyright 2003-2005 Anthony Mills
+ * Copyright 2003-2006 Anthony Mills
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
@@ -19,62 +19,66 @@ class XML_WBXML_DTD_SyncML extends XML_WBXML_DTD {
function init()
{
- $this->setTag(5, 'Add'); // 0x05
- $this->setTag(6, 'Alert'); // 0x06
- $this->setTag(7, 'Archive'); // 0x07
- $this->setTag(8, 'Atomic'); // 0x08
- $this->setTag(9, 'Chal'); // 0x09
- $this->setTag(10, 'Cmd'); // 0x0A
- $this->setTag(11, 'CmdID'); // 0x0B
- $this->setTag(12, 'CmdRef'); // 0x0C
- $this->setTag(13, 'Copy'); // 0x0D
- $this->setTag(14, 'Cred'); // 0x0E
- $this->setTag(15, 'Data'); // 0x0F
+ /* this code table has been extracted from libwbxml
+ * (see http://libwbxml.aymerick.com/) by using
+ *
+ * grep '\"[^\"]*\", *0x.., 0x.. },' wbxml_tables.c
+ * | sed -e 's#^.*\"\([^\"]*\)\", *\(0x..\), \(0x..\) },.*$# \$this->setTag\(\3, \"\1\"\); // \2#g'
+ */
- $this->setTag(16, 'Delete'); // 0x10
- $this->setTag(17, 'Exec'); // 0x11
- $this->setTag(18, 'Final'); // 0x12
- $this->setTag(19, 'Get'); // 0x13
- $this->setTag(20, 'Item'); // 0x14
- $this->setTag(21, 'Lang'); // 0x15
- $this->setTag(22, 'LocName'); // 0x16
- $this->setTag(23, 'LocURI'); // 0x17
- $this->setTag(24, 'Map'); // 0x18
- $this->setTag(25, 'MapItem'); // 0x19
- $this->setTag(26, 'Meta'); // 0x1A
- $this->setTag(27, 'MsgID'); // 0x1B
- $this->setTag(28, 'MsgRef'); // 0x1C
- $this->setTag(29, 'NoRssp'); // 0x1D
- $this->setTag(30, 'NoResults'); // 0x1E
- $this->setTag(31, 'Put'); // 0x1F
-
- $this->setTag(32, 'Replace'); // 0x10
- $this->setTag(33, 'RespURI'); // 0x21
- $this->setTag(34, 'Results'); // 0x22
- $this->setTag(35, 'Search'); // 0x23
- $this->setTag(36, 'Sequence'); // 0x24
- $this->setTag(37, 'SessionID'); // 0x25
- $this->setTag(38, 'SftDel'); // 0x26
- $this->setTag(39, 'Source'); // 0x27
- $this->setTag(40, 'SourceRef'); // 0x28
- $this->setTag(41, 'Status'); // 0x29
- $this->setTag(42, 'Sync'); // 0x2A
- $this->setTag(43, 'SyncBody'); // 0x2B
- $this->setTag(44, 'SyncHdr'); // 0x2C
- $this->setTag(45, 'SyncML'); // 0x2D
- $this->setTag(46, 'Target'); // 0x2E
- $this->setTag(47, 'TargetRef'); // 0x2F
-
- $this->setTag(48, 'Reserved for future use.'); // 0x30
- $this->setTag(49, 'VerDTD'); // 0x31
- $this->setTag(50, 'VerProto'); // 0x32
- $this->setTag(51, 'NumberOfChanged'); // 0x33
- $this->setTag(52, 'MoreData'); // 0x34
+ $this->setTag(0x05, "Add"); // 0x00
+ $this->setTag(0x06, "Alert"); // 0x00
+ $this->setTag(0x07, "Archive"); // 0x00
+ $this->setTag(0x08, "Atomic"); // 0x00
+ $this->setTag(0x09, "Chal"); // 0x00
+ $this->setTag(0x0a, "Cmd"); // 0x00
+ $this->setTag(0x0b, "CmdID"); // 0x00
+ $this->setTag(0x0c, "CmdRef"); // 0x00
+ $this->setTag(0x0d, "Copy"); // 0x00
+ $this->setTag(0x0e, "Cred"); // 0x00
+ $this->setTag(0x0f, "Data"); // 0x00
+ $this->setTag(0x10, "Delete"); // 0x00
+ $this->setTag(0x11, "Exec"); // 0x00
+ $this->setTag(0x12, "Final"); // 0x00
+ $this->setTag(0x13, "Get"); // 0x00
+ $this->setTag(0x14, "Item"); // 0x00
+ $this->setTag(0x15, "Lang"); // 0x00
+ $this->setTag(0x16, "LocName"); // 0x00
+ $this->setTag(0x17, "LocURI"); // 0x00
+ $this->setTag(0x18, "Map"); // 0x00
+ $this->setTag(0x19, "MapItem"); // 0x00
+ $this->setTag(0x1a, "Meta"); // 0x00
+ $this->setTag(0x1b, "MsgID"); // 0x00
+ $this->setTag(0x1c, "MsgRef"); // 0x00
+ $this->setTag(0x1d, "NoResp"); // 0x00
+ $this->setTag(0x1e, "NoResults"); // 0x00
+ $this->setTag(0x1f, "Put"); // 0x00
+ $this->setTag(0x20, "Replace"); // 0x00
+ $this->setTag(0x21, "RespURI"); // 0x00
+ $this->setTag(0x22, "Results"); // 0x00
+ $this->setTag(0x23, "Search"); // 0x00
+ $this->setTag(0x24, "Sequence"); // 0x00
+ $this->setTag(0x25, "SessionID"); // 0x00
+ $this->setTag(0x26, "SftDel"); // 0x00
+ $this->setTag(0x27, "Source"); // 0x00
+ $this->setTag(0x28, "SourceRef"); // 0x00
+ $this->setTag(0x29, "Status"); // 0x00
+ $this->setTag(0x2a, "Sync"); // 0x00
+ $this->setTag(0x2b, "SyncBody"); // 0x00
+ $this->setTag(0x2c, "SyncHdr"); // 0x00
+ $this->setTag(0x2d, "SyncML"); // 0x00
+ $this->setTag(0x2e, "Target"); // 0x00
+ $this->setTag(0x2f, "TargetRef"); // 0x00
+ $this->setTag(0x30, "Reserved for future use"); // 0x00
+ $this->setTag(0x31, "VerDTD"); // 0x00
+ $this->setTag(0x32, "VerProto"); // 0x00
+ $this->setTag(0x33, "NumberOfChanged"); // 0x00
+ $this->setTag(0x34, "MoreData"); // 0x00
if ($this->version == 0) {
- $this->setCodePage(0, '-//SYNCML//DTD SyncML 1.0//EN', 'syncml:syncml');
+ $this->setCodePage(0, '-//SYNCML//DTD SyncML 1.0//EN', 'syncml:syncml1.0');
$this->setCodePage(1, '-//SYNCML//DTD MetInf 1.0//EN', 'syncml:metinf');
- $this->setURI('syncml:syncml');
+ $this->setURI('syncml:syncml1.0');
} else {
$this->setCodePage(0, '-//SYNCML//DTD SyncML 1.1//EN', 'syncml:syncml1.1');
$this->setCodePage(1, '-//SYNCML//DTD MetInf 1.1//EN', 'syncml:metinf1.1');
diff --git a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLDevInf.php b/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLDevInf.php
index fa7f84041e..076236b4ce 100644
--- a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLDevInf.php
+++ b/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLDevInf.php
@@ -3,9 +3,9 @@
include_once 'XML/WBXML/DTD.php';
/**
- * $Horde: framework/XML_WBXML/WBXML/DTD/SyncMLDevInf.php,v 1.5 2005/01/03 13:09:25 jan Exp $
+ * $Horde: framework/XML_WBXML/WBXML/DTD/SyncMLDevInf.php,v 1.11 2006/01/01 21:10:26 jan Exp $
*
- * Copyright 2003-2005 Anthony Mills
+ * Copyright 2003-2006 Anthony Mills
*
* From Binary XML Content Format Specification Version 1.3, 25 July 2001
* found at http://www.wapforum.org
@@ -19,51 +19,58 @@ class XML_WBXML_DTD_SyncMLDevInf extends XML_WBXML_DTD {
function init()
{
- $this->setTag(5, 'CTCap'); // 0x05
- $this->setTag(6, 'CTType'); // 0x06
- $this->setTag(7, 'DataStore'); // 0x07
- $this->setTag(8, 'DataType'); // 0x08
- $this->setTag(9, 'DevID'); // 0x09
- $this->setTag(10, 'DevInf'); // 0x0A
- $this->setTag(11, 'DevTyp'); // 0x0B
- $this->setTag(12, 'DisplayName'); // 0x0C
- $this->setTag(13, 'DSMem'); // 0x0D
- $this->setTag(14, 'Ext'); // 0x0E
- $this->setTag(15, 'FwV'); // 0x0F
- $this->setTag(16, 'HwV'); // 0x10
- $this->setTag(17, 'Man'); // 0x11
- $this->setTag(18, 'MaxGUIDSize'); // 0x12
- $this->setTag(19, 'MaxID'); // 0x13
- $this->setTag(20, 'MaxMem'); // 0x14
- $this->setTag(21, 'Mod'); // 0x15
- $this->setTag(22, 'OEM'); // 0x15
- $this->setTag(23, 'ParamName'); // 0x17
- $this->setTag(24, 'PropName'); // 0x18
- $this->setTag(25, 'Rx'); // 0x19
- $this->setTag(26, 'Rx-Pref'); // 0x1A
- $this->setTag(27, 'SharedMem'); // 0x1B
- $this->setTag(28, 'Size'); // 0x1C
- $this->setTag(29, 'SourceRef'); // 0x1D
- $this->setTag(30, 'SwV'); // 0x1E
- $this->setTag(31, 'SyncCap'); // 0x1F
- $this->setTag(32, 'SyncType'); // 0x20
- $this->setTag(33, 'Tx'); // 0x21
- $this->setTag(34, 'Tx-Pref'); // 0x22
- $this->setTag(35, 'ValEnum'); // 0x23
- $this->setTag(36, 'VerCT'); // 0x24
- $this->setTag(37, 'VerDTD'); // 0x25
- $this->setTag(38, 'Xnam'); // 0x26
- $this->setTag(39, 'Xval'); // 0x27
- $this->setTag(40, 'UTC'); // 0x28
- $this->setTag(41, 'SupportNumberOfChanges'); // 0x29
- $this->setTag(42, 'SupportLargeObjs'); // 0x2A
+ /* this code table has been extracted from libwbxml
+ * (see http://libwbxml.aymerick.com/) by using
+ *
+ * grep '\"[^\"]*\", *0x.., 0x.. },' wbxml_tables.c
+ * | sed -e 's#^.*\"\([^\"]*\)\", *\(0x..\), \(0x..\) },.*$# \$this->setTag\(\3, \"\1\"\); // \2#g'
+ */
+
+ $this->setTag(0x05, "CTCap"); // 0x00
+ $this->setTag(0x06, "CTType"); // 0x00
+ $this->setTag(0x07, "DataStore"); // 0x00
+ $this->setTag(0x08, "DataType"); // 0x00
+ $this->setTag(0x09, "DevID"); // 0x00
+ $this->setTag(0x0a, "DevInf"); // 0x00
+ $this->setTag(0x0b, "DevTyp"); // 0x00
+ $this->setTag(0x0c, "DisplayName"); // 0x00
+ $this->setTag(0x0d, "DSMem"); // 0x00
+ $this->setTag(0x0e, "Ext"); // 0x00
+ $this->setTag(0x0f, "FwV"); // 0x00
+ $this->setTag(0x10, "HwV"); // 0x00
+ $this->setTag(0x11, "Man"); // 0x00
+ $this->setTag(0x12, "MaxGUIDSize"); // 0x00
+ $this->setTag(0x13, "MaxID"); // 0x00
+ $this->setTag(0x14, "MaxMem"); // 0x00
+ $this->setTag(0x15, "Mod"); // 0x00
+ $this->setTag(0x16, "OEM"); // 0x00
+ $this->setTag(0x17, "ParamName"); // 0x00
+ $this->setTag(0x18, "PropName"); // 0x00
+ $this->setTag(0x19, "Rx"); // 0x00
+ $this->setTag(0x1a, "Rx-Pref"); // 0x00
+ $this->setTag(0x1b, "SharedMem"); // 0x00
+ $this->setTag(0x1c, "Size"); // 0x00
+ $this->setTag(0x1d, "SourceRef"); // 0x00
+ $this->setTag(0x1e, "SwV"); // 0x00
+ $this->setTag(0x1f, "SyncCap"); // 0x00
+ $this->setTag(0x20, "SyncType"); // 0x00
+ $this->setTag(0x21, "Tx"); // 0x00
+ $this->setTag(0x22, "Tx-Pref"); // 0x00
+ $this->setTag(0x23, "ValEnum"); // 0x00
+ $this->setTag(0x24, "VerCT"); // 0x00
+ $this->setTag(0x25, "VerDTD"); // 0x00
+ $this->setTag(0x26, "XNam"); // 0x00
+ $this->setTag(0x27, "XVal"); // 0x00
+ $this->setTag(0x28, "UTC"); // 0x00
+ $this->setTag(0x29, "SupportNumberOfChanges"); // 0x00
+ $this->setTag(0x2a, "SupportLargeObjs"); // 0x00
if ($this->version == 0) {
$this->setCodePage(0, '-//SYNCML//DTD DevInf 1.0//EN', 'syncml:devinf');
- $this->setURI('sync:devinf');
+ $this->setURI('syncml:devinf');
} else {
$this->setCodePage(0, '-//SYNCML//DTD DevInf 1.1//EN', 'syncml:devinf1.1');
- $this->setURI('sync:devinf1.1');
+ $this->setURI('syncml:devinf1.1');
}
}
diff --git a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLMetInf.php b/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLMetInf.php
index a93471ce94..84010187cd 100644
--- a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLMetInf.php
+++ b/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLMetInf.php
@@ -3,9 +3,9 @@
include_once 'XML/WBXML/DTD.php';
/**
- * $Horde: framework/XML_WBXML/WBXML/DTD/SyncMLMetInf.php,v 1.5 2005/01/03 13:09:25 jan Exp $
+ * $Horde: framework/XML_WBXML/WBXML/DTD/SyncMLMetInf.php,v 1.9 2006/01/01 21:10:26 jan Exp $
*
- * Copyright 2003-2005 Anthony Mills
+ * Copyright 2003-2006 Anthony Mills
*
* From Binary XML Content Format Specification Version 1.3, 25 July 2001
* found at http://www.wapforum.org
@@ -19,32 +19,40 @@ class XML_WBXML_DTD_SyncMLMetInf extends XML_WBXML_DTD {
function init()
{
- $this->setTag(5, 'Anchor'); // 0x05
- $this->setTag(6, 'EMI'); // 0x06
- $this->setTag(7, 'Format'); // 0x07
- $this->setTag(8, 'FreeID'); // 0x08
- $this->setTag(9, 'FreeMem'); // 0x09
- $this->setTag(10, 'Last'); // 0x0A
- $this->setTag(11, 'Mark'); // 0x0B
- $this->setTag(12, 'MaxMsgSize'); // 0x0C
- $this->setTag(13, 'Mem'); // 0x0D
- $this->setTag(14, 'MetInf'); // 0x0E
- $this->setTag(15, 'Next'); // 0x0F
- $this->setTag(16, 'NextNonce'); // 0x10
- $this->setTag(17, 'SharedMem'); // 0x11
- $this->setTag(18, 'Size'); // 0x12
- $this->setTag(19, 'Type'); // 0x13
- $this->setTag(20, 'Version'); // 0x14
- $this->setTag(21, 'MaxObjSize'); // 0x15
+ /* this code table has been extracted from libwbxml
+ * (see http://libwbxml.aymerick.com/) by using
+ *
+ * grep '\"[^\"]*\", *0x.., 0x.. },' wbxml_tables.c
+ * | sed -e 's#^.*\"\([^\"]*\)\", *\(0x..\), \(0x..\) },.*$# \$this->setTag\(\3, \"\1\"\); // \2#g'
+ */
+
+ $this->setTag(0x05, "Anchor"); // 0x01
+ $this->setTag(0x06, "EMI"); // 0x01
+ $this->setTag(0x07, "Format"); // 0x01
+ $this->setTag(0x08, "FreeID"); // 0x01
+ $this->setTag(0x09, "FreeMem"); // 0x01
+ $this->setTag(0x0a, "Last"); // 0x01
+ $this->setTag(0x0b, "Mark"); // 0x01
+ $this->setTag(0x0c, "MaxMsgSize"); // 0x01
+ $this->setTag(0x15, "MaxObjSize"); // 0x01
+ $this->setTag(0x0d, "Mem"); // 0x01
+ $this->setTag(0x0e, "MetInf"); // 0x01
+ $this->setTag(0x0f, "Next"); // 0x01
+ $this->setTag(0x10, "NextNonce"); // 0x01
+ $this->setTag(0x11, "SharedMem"); // 0x01
+ $this->setTag(0x12, "Size"); // 0x01
+ $this->setTag(0x13, "Type"); // 0x01
+ $this->setTag(0x14, "Version"); // 0x01
if ($this->version == 0) {
- $this->setCodePage(0, '-//SYNCML//DTD SyncML 1.0//EN', 'syncml:syncml');
+ $this->setCodePage(0, '-//SYNCML//DTD SyncML 1.0//EN', 'syncml:SYNCML1.0');
$this->setCodePage(1, '-//SYNCML//DTD MetInf 1.0//EN', 'syncml:metinf');
$this->setURI('syncml:metinf');
} else {
$this->setCodePage(0, '-//SYNCML//DTD SyncML 1.1//EN', 'syncml:syncml1.1');
$this->setCodePage(1, '-//SYNCML//DTD MetInf 1.1//EN', 'syncml:metinf1.1');
$this->setURI('syncml:metinf1.1');
+ //$this->setURI('syncml:metinf'); // for some funny reason, libwbxml produces no :metinf1.1 here
}
}
diff --git a/phpgwapi/inc/horde/XML/WBXML/DTDManager.php b/phpgwapi/inc/horde/XML/WBXML/DTDManager.php
index a855034033..1f57e28195 100644
--- a/phpgwapi/inc/horde/XML/WBXML/DTDManager.php
+++ b/phpgwapi/inc/horde/XML/WBXML/DTDManager.php
@@ -5,9 +5,9 @@ include_once 'XML/WBXML/DTD/SyncMLMetInf.php';
include_once 'XML/WBXML/DTD/SyncMLDevInf.php';
/**
- * $Horde: framework/XML_WBXML/WBXML/DTDManager.php,v 1.4 2005/01/03 13:09:25 jan Exp $
+ * $Horde: framework/XML_WBXML/WBXML/DTDManager.php,v 1.7 2006/01/01 21:10:25 jan Exp $
*
- * Copyright 2003-2005 Anthony Mills
+ * Copyright 2003-2006 Anthony Mills
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
@@ -24,7 +24,7 @@ class XML_WBXML_DTDManager {
function XML_WBXML_DTDManager()
{
- $this->registerDTD('-//SYNCML//DTD SyncML 1.0//EN', 'syncml:syncml', new XML_WBXML_DTD_SyncML(0));
+ $this->registerDTD('-//SYNCML//DTD SyncML 1.0//EN', 'syncml:syncml1.0', new XML_WBXML_DTD_SyncML(0));
$this->registerDTD('-//SYNCML//DTD SyncML 1.1//EN', 'syncml:syncml1.1', new XML_WBXML_DTD_SyncML(1));
$this->registerDTD('-//SYNCML//DTD MetInf 1.0//EN', 'syncml:metinf', new XML_WBXML_DTD_SyncMLMetInf(0));
@@ -50,7 +50,7 @@ class XML_WBXML_DTDManager {
$dtd->setDPI($publicIdentifier);
$this->_strDTD[$publicIdentifier] = $dtd;
- $this->_strDTDURI[$uri] = $dtd;
+ $this->_strDTDURI[strtolower($uri)] = $dtd;
}
}
diff --git a/phpgwapi/inc/horde/XML/WBXML/Decoder.php b/phpgwapi/inc/horde/XML/WBXML/Decoder.php
index fd99b0aba1..aeb4aacc48 100644
--- a/phpgwapi/inc/horde/XML/WBXML/Decoder.php
+++ b/phpgwapi/inc/horde/XML/WBXML/Decoder.php
@@ -5,9 +5,9 @@ include_once 'XML/WBXML/DTDManager.php';
include_once 'XML/WBXML/ContentHandler.php';
/**
- * $Horde: framework/XML_WBXML/WBXML/Decoder.php,v 1.23 2005/01/03 13:09:25 jan Exp $
+ * $Horde: framework/XML_WBXML/WBXML/Decoder.php,v 1.36 2006/01/01 21:10:25 jan Exp $
*
- * Copyright 2003-2005 Anthony Mills
+ * Copyright 2003-2006 Anthony Mills
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
@@ -54,40 +54,39 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
var $_isAttribute;
var $_isData = false;
+ var $_error = false;
+
/**
* The DTD Manager.
- * @var object XML_WBXML_DTDManager $dtdManager
+ *
+ * @var XML_WBXML_DTDManager
*/
var $_dtdManager;
/**
* The string position.
- * @var integer $_strpos
+ *
+ * @var integer
*/
var $_strpos;
- /**
- * Use wbxml2xml from libwbxml.
- * @var string $_wbxml2xml
- */
- var $_wbxml2xml = '/usr/bin/wbxml2xml';
-
- /**
- * Arguments to pass to wbxml2xml.
- * @var string $_wbxml2xml_args
- */
- var $_wbxml2xml_args = '-o - -';
-
/**
* Constructor.
*/
function XML_WBXML_Decoder()
{
- if (empty($this->_wbxml2xml) || !is_executable($this->_wbxml2xml)) {
- $this->_dtdManager = &new XML_WBXML_DTDManager();
- }
+ $this->_dtdManager = &new XML_WBXML_DTDManager();
}
+ /**
+ * Sets the contentHandler that will receive the output of the
+ * decoding.
+ *
+ * @param XML_WBXML_ContentHandler $ch The contentHandler
+ */
+ function setContentHandler(&$ch) {
+ $this->_ch = &$ch;
+ }
/**
* Return one byte from the input stream.
*
@@ -100,91 +99,95 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
/**
* Takes a WBXML input document and returns decoded XML.
+ * However the preferred and more effecient method is to
+ * use decode() rather than decodeToString() and have an
+ * appropriate contentHandler deal with the decoded data.
*
* @param string $wbxml The WBXML document to decode.
*
* @return string The decoded XML document.
*/
+ function decodeToString($wbxml)
+ {
+ $this->_ch = &new XML_WBXML_ContentHandler();
+
+ $r = $this->decode($wbxml);
+ if (is_a($r, 'PEAR_Error')) {
+ return $r;
+ }
+ return $this->_ch->getOutput();
+ }
+
+ /**
+ * Takes a WBXML input document and decodes it.
+ * Decoding result is directly passed to the contentHandler.
+ * A contenthandler must be set using setContentHandler
+ * prior to invocation of this method
+ *
+ * @param string $wbxml The WBXML document to decode.
+ *
+ * @return mixed True on success or PEAR_Error.
+ */
function decode($wbxml)
{
- // Figure out if we're going to use wbxml2xml to do the
- // conversion, or do it all in PHP code.
- if (!empty($this->_wbxml2xml) && is_executable($this->_wbxml2xml)) {
- $descriptorspec = array(
- 0 => array('pipe', 'r'),
- 1 => array('pipe', 'w'),
- );
+ $this->_error = false; // reset state
- $wbxml2xml = proc_open($this->_wbxml2xml . ' ' . $this->_wbxml2xml_args,
- $descriptorspec, $pipes);
- if (is_resource($wbxml2xml)) {
- fwrite($pipes[0], $wbxml);
- fclose($pipes[0]);
+ $this->_strpos = 0;
- // Grab the output of wbxml2xml.
- $xml = '';
- while (!feof($pipes[1])) {
- $xml .= fread($pipes[1], 8192);
- }
- fclose($pipes[1]);
-
- $rv = proc_close($wbxml2xml);
-
- return $xml;
- } else {
- return PEAR::raiseError('wbxml2xml failed');
- }
- } else {
- $this->_strpos = 0;
-
- // Get Version Number from Section 5.4
- // version = u_int8
- // currently 1, 2 or 3
- $this->_wbxmlVersion = $this->getVersionNumber($wbxml);
-
- // Get Document Public Idetifier from Section 5.5
- // publicid = mb_u_int32 | (zero index)
- // zero = u_int8
- // Containing the value zero (0)
- // The actual DPI is determined after the String Table is read.
- $dpiStruct = $this->getDocumentPublicIdentifier($wbxml);
-
- // Get Charset from 5.6
- // charset = mb_u_int32
- $this->_charset = $this->getCharset($wbxml);
-
- // Get String Table from 5.7
- // strb1 = length *byte
- $this->_stringTable = $this->getStringTable($wbxml, $this->_charset);
-
- // Get Document Public Idetifier from Section 5.5.
- $this->_dpi = $this->getDocumentPublicIdentifierImpl($dpiStruct['dpiType'],
- $dpiStruct['dpiNumber'],
- $this->_stringTable);
-
- // Now the real fun begins.
- // From Sections 5.2 and 5.8
-
- // Default content handler.
- $this->_ch = &new XML_WBXML_ContentHandler();
-
- // Default content handler.
- $this->_dtdManager = &new XML_WBXML_DTDManager();
-
- // Get the starting DTD.
- $this->_tagDTD = $this->_dtdManager->getInstance($this->_dpi);
- if (!$this->_tagDTD) {
- return $this->raiseError('No DTD found for ' . $this->_dpi);
- }
-
- $this->_attributeDTD = $this->_tagDTD;
-
- while ($this->_strpos < strlen($wbxml)) {
- $this->_decode($wbxml);
- }
-
- return $this->_ch->getOutput();
+ if (empty($this->_ch)) {
+ return $this->raiseError('No Contenthandler defined.');
}
+
+ // Get Version Number from Section 5.4
+ // version = u_int8
+ // currently 1, 2 or 3
+ $this->_wbxmlVersion = $this->getVersionNumber($wbxml);
+
+ // Get Document Public Idetifier from Section 5.5
+ // publicid = mb_u_int32 | (zero index)
+ // zero = u_int8
+ // Containing the value zero (0)
+ // The actual DPI is determined after the String Table is read.
+ $dpiStruct = $this->getDocumentPublicIdentifier($wbxml);
+
+ // Get Charset from 5.6
+ // charset = mb_u_int32
+ $this->_charset = $this->getCharset($wbxml);
+
+ // Get String Table from 5.7
+ // strb1 = length *byte
+ $this->retrieveStringTable($wbxml);
+
+ // Get Document Public Idetifier from Section 5.5.
+ $this->_dpi = $this->getDocumentPublicIdentifierImpl($dpiStruct['dpiType'],
+ $dpiStruct['dpiNumber'],
+ $this->_stringTable);
+
+ // Now the real fun begins.
+ // From Sections 5.2 and 5.8
+
+
+ // Default content handler.
+ $this->_dtdManager = &new XML_WBXML_DTDManager();
+
+ // Get the starting DTD.
+ $this->_tagDTD = $this->_dtdManager->getInstance($this->_dpi);
+
+ if (!$this->_tagDTD) {
+ return $this->raiseError('No DTD found for '
+ . $this->_dpi . '/'
+ . $dpiStruct['dpiNumber']);
+ }
+
+ $this->_attributeDTD = $this->_tagDTD;
+print "starting at: ".$this->_strpos."\n";
+ while (empty($this->_error) && $this->_strpos < strlen($wbxml)) {
+ $this->_decode($wbxml);
+ }
+ if (!empty($this->_error)) {
+ return $this->_error;
+ }
+ return true;
}
function getVersionNumber($input)
@@ -194,28 +197,22 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
function getDocumentPublicIdentifier($input)
{
- // 'dpiType' 'dpiNumber'
- $dpistruct = array();
-
$i = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
-
if ($i == 0) {
- $dpiStruct['dpiType'] = 2;
- $dpiStruct['dpiNumber'] = $this->getByte($input);
+ return array('dpiType' => 2,
+ 'dpiNumber' => $this->getByte($input));
} else {
- $dpiStruct['dpiType'] = 1;
- $dpiStruct['dpiNumber'] = $i;
+ return array('dpiType' => 1,
+ 'dpiNumber' => $i);
}
-
- return $dpiStruct;
}
- function getDocumentPublicIdentifierImpl($dpiType, $dpiNumber, $st)
+ function getDocumentPublicIdentifierImpl($dpiType, $dpiNumber)
{
if ($dpiType == 1) {
return XML_WBXML::getDPIString($dpiNumber);
} else {
- return isset($st[$dpiNumber]) ? $st[$dpiNumber] : null;
+ return $this->getStringTableEntry($dpiNumber);
}
}
@@ -228,43 +225,56 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
function getCharset($input)
{
$cs = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
- return $charset = XML_WBXML::getCharsetString($cs);
+ return XML_WBXML::getCharsetString($cs);
}
/**
- * @TODO needs to be fixed. Does this still really need to be
- * fixed?
+ * Retrieves the string table.
+ * The string table consists of an mb_u_int32 length
+ * and then length bytes forming the table.
+ * References to the string table refer to the
+ * starting position of the (null terminated)
+ * string in this table.
*/
- function getStringTable($input, $cs)
+ function retrieveStringTable($input)
{
- $stringTable = array();
$size = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
+ $this->_stringTable = substr($input, $this->_strpos, $size);
+ $this->_strpos += $size;
+ // print "stringtable($size):" . $this->_stringTable ."\n";
+ }
- // A hack to make it work with arrays.
- // How/why is this necessary?
- $str = 'j';
+ function getStringTableEntry($index)
+ {
+ if ($index >= strlen($this->_stringTable)) {
+ $this->_error =
+ $this->_ch->raiseError('Invalid offset ' . $index
+ . ' value encountered around position '
+ . $this->_strpos
+ . '. Broken wbxml?');
+ return '';
+ }
- $numstr = 0;
- $start = 0;
- $j = 0;
- for ($i = 0; $i < $size; $i++ ) {
- /* May need to fix the null detector for more than single
- * byte charsets like ASCII, UTF-8, etc. */
- $ch = $input[$this->_strpos++];
- if (ord($ch) == 0) {
- $stringTable[$numstr++] = $str;
- $str = '#';
- $start = $i + 1;
- } else {
- $str[$j++] = $ch;
+ // copy of method termstr but without modification of this->_strpos
+
+ $str = '#'; // must start with nonempty string to allow array access
+
+ $i = 0;
+ $ch = $this->_stringTable[$index++];
+ if (ord($ch) == 0) {
+ return ''; // don't return '#'
+ }
+
+ while (ord($ch) != 0) {
+ $str[$i++] = $ch;
+ if ($index >= strlen($this->_stringTable)) {
+ break;
}
+ $ch = $this->_stringTable[$index++];
}
-
- if ($start < $size) {
- $stringTable[$numstr++] = $str;
- }
-
- return $stringTable;
+ // print "string table entry: $str\n";
+ return $str;
+
}
function _decode($input)
@@ -272,16 +282,20 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
$token = $this->getByte($input);
$str = '';
+ #print "position: " . $this->_strpos . " token: " . $token . " str10: " . substr($input, $this->_strpos, 10) . "\n"; // @todo: remove debug output
+
switch ($token) {
case XML_WBXML_GLOBAL_TOKEN_STR_I:
// Section 5.8.4.1
$str = $this->termstr($input);
$this->_ch->characters($str);
+ // print "str:$str\n"; // @TODO Remove debug code
break;
case XML_WBXML_GLOBAL_TOKEN_STR_T:
// Section 5.8.4.1
- $str = $this->_stringTable[XML_WBXML::MBUInt32ToInt($intput)];
+ $x = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
+ $str = $this->getStringTableEntry($x);
$this->_ch->characters($str);
break;
@@ -297,7 +311,7 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
case XML_WBXML_GLOBAL_TOKEN_EXT_T_1:
case XML_WBXML_GLOBAL_TOKEN_EXT_T_2:
// Section 5.8.4.2
- $str = $this->_stringTable[XML_WBXML::MBUInt32ToInt($intput)];
+ $str = $this->getStringTableEnty(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
$this->_ch->characters($str);
break;
@@ -319,40 +333,65 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
case XML_WBXML_GLOBAL_TOKEN_PI:
// Section 5.8.4.4
- // throw new IOException("WBXML global token processing instruction(PI, " + token + ") is unsupported!");
+ // throw new IOException
+ // die("WBXML global token processing instruction(PI, " + token + ") is unsupported!\n");
break;
case XML_WBXML_GLOBAL_TOKEN_LITERAL:
// Section 5.8.4.5
- $str = $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
+ $str = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
$this->parseTag($input, $str, false, false);
break;
case XML_WBXML_GLOBAL_TOKEN_LITERAL_A:
// Section 5.8.4.5
- $str = $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
+ $str = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
$this->parseTag($input, $str, true, false);
break;
case XML_WBXML_GLOBAL_TOKEN_LITERAL_AC:
// Section 5.8.4.5
- $str = $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
+ $str = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
$this->parseTag($input, $string, true, true);
break;
case XML_WBXML_GLOBAL_TOKEN_LITERAL_C:
// Section 5.8.4.5
- $str = $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
+ $str = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
$this->parseTag($input, $str, false, true);
break;
case XML_WBXML_GLOBAL_TOKEN_OPAQUE:
// Section 5.8.4.6
$size = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
- $b = substr($input, $this->_strpos, $this->_strpos + $size);
+ // print "opaque of size $size\n"; // @todo remove debug
+ $b = substr($input, $this->_strpos, $size);
$this->_strpos += $size;
- $this->_ch->opaque($b);
+ // opaque data inside a element may or may not be
+ // a nested wbxml document (for example devinf data).
+ // We find out by checking the first byte of the data: if it's
+ // 1, 2 or 3 we expect it to be the version number of a wbxml
+ // document and thus start a new wbxml decoder instance on it.
+
+ if ($this->_isData && ord($b) <= 10) {
+ $decoder = &new XML_WBXML_Decoder(true);
+ $decoder->setContentHandler($this->_ch);
+ $s = $decoder->decode($b);
+ // /* // @todo: FIXME currently we can't decode Nokia
+ // DevInf data. So ignore error for the time beeing.
+ if (is_a($s, 'PEAR_Error')) {
+ $this->_error = $s;
+ return;
+ }
+ // */
+ // $this->_ch->characters($s);
+ } else {
+ /* normal opaque behaviour: just copy the raw data: */
+ $this->_ch->characters( $b);
+ }
+
+ // old approach to deal with opaque data inside ContentHandler:
// FIXME Opaque is used by SYNCML. Opaque data that depends on the context
// if (contentHandler instanceof OpaqueContentHandler) {
// ((OpaqueContentHandler)contentHandler).opaque(b);
@@ -363,8 +402,6 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
// contentHandler.characters(chars, 0, chars.length);
// }
- // This can cause some problems. We may have to use a
- // event based decoder.
break;
case XML_WBXML_GLOBAL_TOKEN_END:
@@ -375,6 +412,7 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
case XML_WBXML_GLOBAL_TOKEN_SWITCH_PAGE:
// Section 5.8.4.7.2
$codePage = $this->getByte($input);
+ // print "switch to codepage $codePage\n"; // @todo: remove debug code
$this->switchElementCodePage($codePage);
break;
@@ -386,11 +424,16 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
$realToken = $token & 0x3F;
$str = $this->getTag($realToken);
+ // print "element:$str\n"; // @TODO Remove debug code
$this->parseTag($input, $str, $hasAttributes, $hasContent);
if ($realToken == 0x0f) {
- // FIXME Don't remember this one.
+ // store if we're inside a Data tag. This may contain
+ // an additional enclosed wbxml document on which we have
+ // to run a seperate encoder
$this->_isData = true;
+ } else {
+ $this->_isData = false;
}
break;
}
@@ -422,10 +465,6 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
$tag = 'Unknown';
}
- if ($tag == 'Data') {
- $this->_isData = false;
- }
-
$this->_ch->endElement($this->getCurrentURI(), $tag);
return $tag;
@@ -453,7 +492,7 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
'value' => $value);
}
- $attr = $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
+ $attr = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
break;
// Value specified.
@@ -468,7 +507,7 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
case XML_WBXML_GLOBAL_TOKEN_EXT_T_1:
case XML_WBXML_GLOBAL_TOKEN_EXT_T_2:
// Section 5.8.4.2
- $value .= $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
+ $value .= $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
break;
case XML_WBXML_GLOBAL_TOKEN_EXT_0:
@@ -490,7 +529,7 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
case XML_WBXML_GLOBAL_TOKEN_STR_T:
// Section 5.8.4.1
- $value .= $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
+ $value .= $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
break;
case XML_WBXML_GLOBAL_TOKEN_OPAQUE:
@@ -600,13 +639,16 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
}
/**
- * @TODO FIXME reads a null terminated string.
+ * Reads a null terminated string.
*/
function termstr($input)
{
- $str = '#';
+ $str = '#'; // must start with nonempty string to allow array access
$i = 0;
$ch = $input[$this->_strpos++];
+ if (ord($ch) == 0) {
+ return ''; // don't return '#'
+ }
while (ord($ch) != 0) {
$str[$i++] = $ch;
$ch = $input[$this->_strpos++];
@@ -616,3 +658,4 @@ class XML_WBXML_Decoder extends XML_WBXML_ContentHandler {
}
}
+
diff --git a/phpgwapi/inc/horde/XML/WBXML/Encoder.php b/phpgwapi/inc/horde/XML/WBXML/Encoder.php
index 2fa11ba183..729c360f6c 100644
--- a/phpgwapi/inc/horde/XML/WBXML/Encoder.php
+++ b/phpgwapi/inc/horde/XML/WBXML/Encoder.php
@@ -6,9 +6,9 @@ include_once 'XML/WBXML/DTDManager.php';
include_once 'Horde/String.php';
/**
- * $Horde: framework/XML_WBXML/WBXML/Encoder.php,v 1.27 2005/01/03 13:09:25 jan Exp $
+ * $Horde: framework/XML_WBXML/WBXML/Encoder.php,v 1.39 2006/01/01 21:10:25 jan Exp $
*
- * Copyright 2003-2005 Anthony Mills
+ * Copyright 2003-2006 Anthony Mills
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
@@ -36,105 +36,59 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
var $_currentURI;
- var $_subParser;
+ var $_subParser = null;
var $_subParserStack = 0;
-
- /**
- * These will store the startElement params to see if we should
- * call startElementImp or startEndElementImp.
- */
- var $_storeURI;
- var $_storeName;
- var $_storeAttributes;
-
+
/**
* The XML parser.
- * @var resource $_parser
+ *
+ * @var resource
*/
var $_parser;
/**
* The DTD Manager.
- * @var object XML_WBXML_DTDManager $dtdManager
+ *
+ * @var XML_WBXML_DTDManager
*/
var $_dtdManager;
- var $_indent = 0;
-
- /**
- * Use wbxml2xml from libwbxml.
- * @var string $_xml2wbxml
- */
- var $_xml2wbxml = '/usr/bin/xml2wbxml';
-
- /**
- * Arguments to pass to xml2wbxml.
- * @var string $_xml2wbxml_args
- */
- var $_xml2wbxml_args = '-k -n -v 1.2 -o - -';
-
/**
* Constructor.
*/
function XML_WBXML_Encoder()
{
- if (empty($this->_xml2wbxml) || !is_executable($this->_xml2wbxml)) {
- $this->_stringTable = &new XML_WBXML_HashTable();
- $this->_dtdManager = &new XML_WBXML_DTDManager();
- }
+ $this->_dtdManager = &new XML_WBXML_DTDManager();
+ $this->_stringTable = &new XML_WBXML_HashTable();
}
/**
- * Take the input $xml and turn it into WBXML.
+ * Take the input $xml and turn it into WBXML. This is _not_ the
+ * intended way of using this class. It is derived from
+ * Contenthandler and one should use it as a ContentHandler and
+ * produce the XML-structure with startElement(), endElement(),
+ * and characters().
*/
function encode($xml)
{
- if (!empty($this->_xml2wbxml) && is_executable($this->_xml2wbxml)) {
- $descriptorspec = array(
- 0 => array('pipe', 'r'),
- 1 => array('pipe', 'w'),
- );
+ // 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_processing_instruction_handler($this->_parser, '');
+ xml_set_external_entity_ref_handler($this->_parser, '');
- $xml2wbxml = proc_open($this->_xml2wbxml . ' ' . $this->_xml2wbxml_args,
- $descriptorspec, $pipes);
- if (is_resource($xml2wbxml)) {
- fwrite($pipes[0], $xml);
- fclose($pipes[0]);
-
- // Grab the output of xml2wbxml.
- $wbxml = '';
- while (!feof($pipes[1])) {
- $wbxml .= fread($pipes[1], 8192);
- }
- fclose($pipes[1]);
-
- $rv = proc_close($xml2wbxml);
-
- return $wbxml;
- } else {
- return PEAR::raiseError('xml2wbxml failed');
- }
- } else {
- // 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);
-
- return $this->_output;
+ 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);
+
+ return $this->_output;
}
/**
@@ -142,6 +96,7 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
*/
function writeHeader($uri)
{
+ error_log("getInstanceURI($uri)");
$this->_dtd = &$this->_dtdManager->getInstanceURI($uri);
$dpiString = $this->_dtd->getDPI();
@@ -256,57 +211,25 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
return array($uri, $name);
}
- /**
- * Has no content, 64.
- */
- function startEndElementImp($uri, $name, $attributes)
- {
- if (!$this->_hasWrittenHeader) {
- $this->writeHeader($uri);
- }
-
- $this->writeTag($name, $attributes, false, $this->_charset);
- }
-
- function startElementImp($uri, $name, $attributes)
- {
- if (!$this->_hasWrittenHeader) {
- $this->writeHeader($uri);
- }
-
- if ($this->_currentURI != $uri) {
- $this->changecodepage($uri);
-
- $this->_currentURI != $uri;
- }
-
- $this->writeTag($name, $attributes, true, $this->_charset);
- }
-
- function writeStartElement($isEnd)
- {
- if ($this->_storeName != null) {
- if ($isEnd) {
- $this->startEndElementImp($this->_storeURI, $this->_storeName, $this->_storeAttributes);
- } else {
- $this->startElementImp($this->_storeURI, $this->_storeName, $this->_storeAttributes);
- }
-
- $this->_storeURI = null;
- $this->_storeName = null;
- $this->_storeAttributes = null;
- }
- }
-
function startElement($uri, $name, $attributes)
{
+ error_log("startElement::: <$name>");
+# error_log(" subparser is:: ".$this->_subParser);
if ($this->_subParser == null) {
- $this->writeStartElement(false);
- $this->_storeURI = $uri;
- $this->_storeName = $name;
- $this->_storeAttributes = $attributes;
+ if (!$this->_hasWrittenHeader) {
+ $this->writeHeader($uri);
+ }
+ if ($this->_currentURI != $uri) {
+ $this->changecodepage($uri);
+ }
+ if ($this->_subParser == null) {
+ $this->writeTag($name, $attributes, true, $this->_charset);
+ } else {
+ $this->_subParser->startElement($uri,$name, $attributes);
+ }
} else {
$this->_subParserStack++;
+ $this->_subParser->startElement($uri,$name,$attributes);
}
}
@@ -320,8 +243,6 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
function opaque($bytes)
{
if ($this->_subParser == null) {
- $this->writeStartElement(false);
-
$this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE);
XML_WBXML::intToMBUInt32($this->_output, count($bytes));
$this->_output .= $bytes;
@@ -331,12 +252,11 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
function characters($chars)
{
$chars = trim($chars);
+ error_log("characters ::: ".$chars);
if (strlen($chars)) {
/* We definitely don't want any whitespace. */
if ($this->_subParser == null) {
- $this->writeStartElement(false);
-
$i = $this->_stringTable->get($chars);
if ($i != null) {
$this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_T);
@@ -345,6 +265,8 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
$this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_I);
$this->writeString($chars, $this->_charset);
}
+ } else {
+ $this->_subParser->characters($chars);
}
}
}
@@ -354,17 +276,15 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
$this->characters($chars);
}
- function defaultHandler($parser, $data)
- {
- }
-
function writeTag($name, $attrs, $hasContent, $cs)
{
+
if ($attrs != null && !count($attrs)) {
$attrs = null;
}
$t = $this->_dtd->toTagInt($name);
+# error_log("writeTag ::: -> $name $t");
if ($t == -1) {
$i = $this->_stringTable->get($name);
if ($i == null) {
@@ -394,7 +314,7 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
}
}
- if ($attrs != null) {
+ if ($attrs != null && is_array($attrs) && count($attrs) > 0 ) {
$this->writeAttributes($attrs, $cs);
}
}
@@ -435,13 +355,23 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
function endElement($uri, $name)
{
+ error_log("endElement ::: $name>");
+# error_log(" subparser is: ".$this->_subParser);
if ($this->_subParser == null) {
- $this->writeStartElement(false);
$this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_END);
+# error_log(" _output is: ".strlen($this->_output));
} else {
+ $this->_subParser->endElement($uri, $name);
$this->_subParserStack--;
+
if ($this->_subParserStack == 0) {
- unset($this->_subParser);
+ $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE);
+
+ XML_WBXML::intToMBUInt32($this->_output,
+ strlen($this->_subParser->getOutput()));
+ $this->_output .= $this->_subParser->getOutput();
+
+ $this->_subParser = null;
}
}
}
@@ -454,33 +384,37 @@ class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
function changecodepage($uri)
{
+# error_log("changecodepage::: $uri");
+ // @todo: this is a hack!
+ if (!preg_match('/1\.1$/', $uri)) {
+ $uri .= '1.1';
+ }
$cp = $this->_dtd->toCodePageURI($uri);
-
+# error_log("--- \$cp:: $cp");
if (strlen($cp)) {
$this->_dtd = &$this->_dtdManager->getInstanceURI($uri);
$this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_SWITCH_PAGE);
$this->_output .= chr($cp);
+ $this->_currentURI = $uri;
+
} else {
- $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE);
-
- $this->_subParser = &new XML_WBXML_Encoder($this->_output);
- $this->startElement($this->_storeURI, $this->_storeName, $this->_storeAttributes);
-
- $this->_subParserStack = 2;
-
- $this->_storeURI = null;
- $this->_storeName = null;
- $this->_storeAttributes = null;
+ $this->_subParser = &new XML_WBXML_Encoder(true);
+ $this->_subParserStack = 1;
}
}
/**
* Getter for property output.
*/
- function getOutput($output)
+ function getOutput()
{
return $this->_output;
}
+ function getOutputSize()
+ {
+ return strlen($this->_output);
+ }
+
}