updated WBXML code to work without external binary

many thanks to the horde project for writing very good code!!
This commit is contained in:
Lars Kneschke 2006-01-11 05:42:07 +00:00
parent 51c43c997f
commit fce1d83932
18 changed files with 745 additions and 681 deletions

View File

@ -7,22 +7,24 @@
* - Introspection documentation and method signatures.
*
* EXAMPLE:
* <code>
* $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')));
* </code>
*
* $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 <jan@horde.org>
* Copyright 2002-2006 Jan Schneider <jan@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 Jan Schneider <jan@horde.org>
* @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)
{

View File

@ -1,25 +1,24 @@
<?php
include_once 'Horde/RPC.php';
include_once 'Horde/SyncML.php';
#include_once 'Horde/SyncML/State.php';
include_once 'Horde/SyncML/State_egw.php';
include_once 'Horde/SyncML/Command/Status.php';
require_once 'Horde/SyncML.php';
#require_once 'Horde/SyncML/State.php';
require_once 'Horde/SyncML/State_egw.php';
require_once 'Horde/SyncML/Command/Status.php';
/**
* The Horde_RPC_syncml class provides a SyncML implementation of the
* Horde RPC system.
* The Horde_RPC_syncml class provides a SyncML implementation of the Horde
* RPC system.
*
* $Horde: framework/RPC/RPC/syncml.php,v 1.18 2004/07/13 03:06:12 chuck Exp $
* $Horde: framework/RPC/RPC/syncml.php,v 1.27 2006/01/01 21:10:11 jan Exp $
*
* Copyright 2003-2004 Chuck Hagenbuch <chuck@horde.org>, Anthony Mills <amills@pyramid6.com>
* Copyright 2003-2006 Chuck Hagenbuch <chuck@horde.org>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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@horde.org>
* @author Anthony Mills <amills@pyramid6.com>
* @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 </SyncHdr></SyncML> or </SyncBody></SyncML>
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);

View File

@ -1,23 +1,23 @@
<?php
include_once 'Horde/RPC/syncml.php';
include_once 'XML/WBXML/Decoder.php';
include_once 'XML/WBXML/Encoder.php';
require_once dirname(__FILE__) . '/syncml.php';
require_once 'XML/WBXML/Decoder.php';
require_once 'XML/WBXML/Encoder.php';
/**
* The Horde_RPC_syncml class provides a SyncML implementation of the Horde
* RPC system.
* The Horde_RPC_syncml_wbxml class provides a SyncML implementation of the
* Horde RPC system using WBXML encoding.
*
* $Horde: framework/RPC/RPC/syncml_wbxml.php,v 1.11 2004/07/13 03:06:12 chuck Exp $
* $Horde: framework/RPC/RPC/syncml_wbxml.php,v 1.18 2006/01/01 21:10:11 jan Exp $
*
* Copyright 2003-2004 Chuck Hagenbuch <chuck@horde.org>, Anthony Mills <amills@pyramid6.com>
* Copyright 2003-2006 Chuck Hagenbuch <chuck@horde.org>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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@horde.org>
* @author Anthony Mills <amills@pyramid6.com>
* @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.
*/

View File

@ -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);

View File

@ -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', '<DevInf xmlns="syncml:devinf"><VerDTD>1.0</VerDTD><Man>The Horde Framework</Man><DevID>4711</DevID><DevTyp>workstation</DevTyp><DataStore><SourceRef>./contacts</SourceRef><Rx-Pref><CTType>text/x-vcard</CTType><VerCT>2.1</VerCT></Rx-Pref><Tx-Pref><CTType>text/x-vcard</CTType><VerCT>2.1</VerCT></Tx-Pref><SyncCap><SyncType>1</SyncType><SyncType>2</SyncType><SyncType>3</SyncType><SyncType>4</SyncType><SyncType>5</SyncType><SyncType>6</SyncType><SyncType>7</SyncType></SyncCap></DataStore><DataStore><SourceRef>./calendar</SourceRef><Rx-Pref><CTType>text/x-vcalendar</CTType><VerCT>2.0</VerCT></Rx-Pref><Rx><CTType>text/x-vcalendar</CTType><VerCT>1.0</VerCT></Rx><Tx-Pref><CTType>text/x-vcalendar</CTType><VerCT>2.0</VerCT></Tx-Pref><Tx><CTType>text/x-vcalendar</CTType><VerCT>1.0</VerCT></Tx><SyncCap><SyncType>1</SyncType><SyncType>2</SyncType><SyncType>3</SyncType><SyncType>4</SyncType><SyncType>5</SyncType><SyncType>6</SyncType><SyncType>7</SyncType></SyncCap></DataStore><CTCap><CTType>text/x-vcalendar</CTType><PropName>BEGIN</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><PropName>DTSTART</PropName><PropName>DTEND</PropName><PropName>DTSTAMP</PropName><PropName>SEQUENCE</PropName><PropName>END</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><PropName>UID</PropName><PropName>SUMMARY</PropName><PropName>VERSION</PropName><ValEnum>1.0</ValEnum><PropName>AALARM</PropName><PropName>CATEGORIES</PropName><PropName>CLASS</PropName><PropName>DALARM</PropName><PropName>EXDATE</PropName><PropName>RESOURCES</PropName><PropName>STATUS</PropName><PropName>ATTACH</PropName><PropName>ATTENDEE</PropName><PropName>DCREATED</PropName><PropName>COMPLETED</PropName><PropName>DESCRIPTION</PropName><PropName>DUE</PropName><PropName>LAST-MODIFIED</PropName><PropName>LOCATION</PropName><PropName>PRIORITY</PropName><PropName>RELATED-TO</PropName><PropName>RRULE</PropName><PropName>TRANSP</PropName><PropName>URL</PropName></CTCap><CTCap><CTType>text/calendar</CTType><PropName>BEGIN</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><ValEnum>VALARM</ValEnum><PropName>DTSTART</PropName><PropName>DTEND</PropName><PropName>DTSTAMP</PropName><PropName>SEQUENCE</PropName><PropName>END</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><ValEnum>VALARM</ValEnum><PropName>UID</PropName><PropName>SUMMARY</PropName><PropName>VERSION</PropName><ValEnum>2.0</ValEnum><PropName>CATEGORIES</PropName><PropName>CLASS</PropName><PropName>DALARM</PropName><PropName>EXDATE</PropName><PropName>RESOURCES</PropName><PropName>STATUS</PropName><PropName>ATTACH</PropName><PropName>ATTENDEE</PropName><PropName>DCREATED</PropName><PropName>COMPLETED</PropName><PropName>DESCRIPTION</PropName><PropName>DUE</PropName><PropName>LAST-MODIFIED</PropName><PropName>LOCATION</PropName><PropName>PRIORITY</PropName><PropName>RELATED-TO</PropName><PropName>TRANSP</PropName><PropName>URL</PropName><PropName>RRULE</PropName><PropName>COMMMENT</PropName><PropName>ACTION</PropName><PropName>TRIGGER</PropName><PropName>DURATION</PropName><PropName>REPEAT</PropName></CTCap><CTCap><CTType>text/x-vcard</CTType><PropName>BEGIN</PropName><ValEnum>VCARD</ValEnum><PropName>END</PropName><ValEnum>VCARD</ValEnum><PropName>VERSION</PropName><ValEnum>2.1</ValEnum><PropName>ENCODING</PropName><PropName>VALUE</PropName><PropName>CHARSET</PropName><PropName>FN</PropName><PropName>N</PropName><PropName>NAME</PropName><PropName>NICKNAME</PropName><PropName>PHOTO</PropName><PropName>BDAY</PropName><PropName>ADR</PropName><PropName>LABEL</PropName><PropName>TEL</PropName><PropName>EMAIL</PropName><PropName>MAILER</PropName><PropName>TZ</PropName><PropName>GEO</PropName><PropName>TITLE</PropName><PropName>ROLE</PropName><PropName>LOGO</PropName><PropName>AGENT</PropName><PropName>ORG</PropName><PropName>CATEGORIES</PropName><PropName>NOTE</PropName><PropName>PRODID</PropName><PropName>REV</PropName><PropName>SORT-STRING</PropName><PropName>SOUND</PropName><PropName>URL</PropName><PropName>UID</PropName><PropName>CLASS</PropName><PropName>KEY</PropName></CTCap></DevInf>');
define('DEFAULT_DEFINF_11', '<DevInf xmlns="syncml:devinf"><VerDTD>1.1</VerDTD><Man>The Horde Framework</Man><DevID>4711</DevID><DevTyp>workstation</DevTyp><DataStore><SourceRef>./contacts</SourceRef><Rx-Pref><CTType>text/x-vcard</CTType><VerCT>2.1</VerCT></Rx-Pref><Tx-Pref><CTType>text/x-vcard</CTType><VerCT>2.1</VerCT></Tx-Pref><SyncCap><SyncType>1</SyncType><SyncType>2</SyncType><SyncType>3</SyncType><SyncType>4</SyncType><SyncType>5</SyncType><SyncType>6</SyncType><SyncType>7</SyncType></SyncCap></DataStore><DataStore><SourceRef>./calendar</SourceRef><Rx-Pref><CTType>text/x-vcalendar</CTType><VerCT>2.0</VerCT></Rx-Pref><Rx><CTType>text/x-vcalendar</CTType><VerCT>1.0</VerCT></Rx><Tx-Pref><CTType>text/x-vcalendar</CTType><VerCT>2.0</VerCT></Tx-Pref><Tx><CTType>text/x-vcalendar</CTType><VerCT>1.0</VerCT></Tx><SyncCap><SyncType>1</SyncType><SyncType>2</SyncType><SyncType>3</SyncType><SyncType>4</SyncType><SyncType>5</SyncType><SyncType>6</SyncType><SyncType>7</SyncType></SyncCap></DataStore><CTCap><CTType>text/x-vcalendar</CTType><PropName>BEGIN</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><PropName>DTSTART</PropName><PropName>DTEND</PropName><PropName>DTSTAMP</PropName><PropName>SEQUENCE</PropName><PropName>END</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><PropName>UID</PropName><PropName>SUMMARY</PropName><PropName>VERSION</PropName><ValEnum>1.0</ValEnum><PropName>AALARM</PropName><PropName>CATEGORIES</PropName><PropName>CLASS</PropName><PropName>DALARM</PropName><PropName>EXDATE</PropName><PropName>RESOURCES</PropName><PropName>STATUS</PropName><PropName>ATTACH</PropName><PropName>ATTENDEE</PropName><PropName>DCREATED</PropName><PropName>COMPLETED</PropName><PropName>DESCRIPTION</PropName><PropName>DUE</PropName><PropName>LAST-MODIFIED</PropName><PropName>LOCATION</PropName><PropName>PRIORITY</PropName><PropName>RELATED-TO</PropName><PropName>RRULE</PropName><PropName>TRANSP</PropName><PropName>URL</PropName></CTCap><CTCap><CTType>text/calendar</CTType><PropName>BEGIN</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><ValEnum>VALARM</ValEnum><PropName>DTSTART</PropName><PropName>DTEND</PropName><PropName>DTSTAMP</PropName><PropName>SEQUENCE</PropName><PropName>END</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><ValEnum>VALARM</ValEnum><PropName>UID</PropName><PropName>SUMMARY</PropName><PropName>VERSION</PropName><ValEnum>2.0</ValEnum><PropName>CATEGORIES</PropName><PropName>CLASS</PropName><PropName>DALARM</PropName><PropName>EXDATE</PropName><PropName>RESOURCES</PropName><PropName>STATUS</PropName><PropName>ATTACH</PropName><PropName>ATTENDEE</PropName><PropName>DCREATED</PropName><PropName>COMPLETED</PropName><PropName>DESCRIPTION</PropName><PropName>DUE</PropName><PropName>LAST-MODIFIED</PropName><PropName>LOCATION</PropName><PropName>PRIORITY</PropName><PropName>RELATED-TO</PropName><PropName>TRANSP</PropName><PropName>URL</PropName><PropName>RRULE</PropName><PropName>COMMMENT</PropName><PropName>ACTION</PropName><PropName>TRIGGER</PropName><PropName>DURATION</PropName><PropName>REPEAT</PropName></CTCap><CTCap><CTType>text/x-vcard</CTType><PropName>BEGIN</PropName><ValEnum>VCARD</ValEnum><PropName>END</PropName><ValEnum>VCARD</ValEnum><PropName>VERSION</PropName><ValEnum>2.1</ValEnum><PropName>ENCODING</PropName><PropName>VALUE</PropName><PropName>CHARSET</PropName><PropName>FN</PropName><PropName>N</PropName><PropName>NAME</PropName><PropName>NICKNAME</PropName><PropName>PHOTO</PropName><PropName>BDAY</PropName><PropName>ADR</PropName><PropName>LABEL</PropName><PropName>TEL</PropName><PropName>EMAIL</PropName><PropName>MAILER</PropName><PropName>TZ</PropName><PropName>GEO</PropName><PropName>TITLE</PropName><PropName>ROLE</PropName><PropName>LOGO</PropName><PropName>AGENT</PropName><PropName>ORG</PropName><PropName>CATEGORIES</PropName><PropName>NOTE</PropName><PropName>PRODID</PropName><PropName>REV</PropName><PropName>SORT-STRING</PropName><PropName>SOUND</PropName><PropName>URL</PropName><PropName>UID</PropName><PropName>CLASS</PropName><PropName>KEY</PropName></CTCap></DevInf>');
#define('DEFAULT_DEFINF', '<DevInf xmlns="syncml:devinf"><VerDTD>1.0</VerDTD><Man>The Horde Framework</Man><DevID>4711</DevID>'.
#'<DevTyp>workstation</DevTyp><DataStore><SourceRef>contacts</SourceRef><Rx-Pref><CTType>text/x-vcard</CTType><VerCT>2.1</VerCT>'.
#'</Rx-Pref><Tx-Pref><CTType>text/x-vcard</CTType><VerCT>2.1</VerCT></Tx-Pref><SyncCap><SyncType>1</SyncType><SyncType>2</SyncType><SyncType>7</SyncType></SyncCap>'.
#'</DataStore>'.
#
#'<DataStore><SourceRef>calendar</SourceRef><Rx-Pref><CTType>text/x-vcalendar</CTType><VerCT>2.0</VerCT></Rx-Pref><Rx>'.
#'<CTType>text/x-vcalendar</CTType><VerCT>1.0</VerCT></Rx><Tx-Pref><CTType>text/x-vcalendar</CTType><VerCT>2.0</VerCT></Tx-Pref>'.
#'<Tx><CTType>text/x-vcalendar</CTType><VerCT>1.0</VerCT></Tx><SyncCap><SyncType>1</SyncType><SyncType>7</SyncType></SyncCap></DataStore>'.
#
#'<CTCap><CTType>text/x-vcalendar</CTType><PropName>BEGIN</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum>'.
#'<ValEnum>VTODO</ValEnum><PropName>DTSTART</PropName><PropName>DTEND</PropName><PropName>DTSTAMP</PropName><PropName>SEQUENCE</PropName>'.
#'<PropName>END</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><PropName>UID</PropName><PropName>'.
#'SUMMARY</PropName><PropName>VERSION</PropName><ValEnum>1.0</ValEnum><PropName>AALARM</PropName><PropName>CATEGORIES</PropName><PropName>',
#'CLASS</PropName><PropName>DALARM</PropName><PropName>EXDATE</PropName><PropName>RESOURCES</PropName><PropName>STATUS</PropName><PropName>',
#'ATTACH</PropName><PropName>ATTENDEE</PropName><PropName>DCREATED</PropName><PropName>COMPLETED</PropName><PropName>DESCRIPTION</PropName>'.
#'<PropName>DUE</PropName><PropName>LAST-MODIFIED</PropName><PropName>LOCATION</PropName><PropName>PRIORITY</PropName>'.
#'<PropName>RELATED-TO</PropName><PropName>RRULE</PropName><PropName>TRANSP</PropName><PropName>URL</PropName></CTCap><CTCap>'.
#'<CTType>text/calendar</CTType><PropName>BEGIN</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum>'.
#'<ValEnum>VALARM</ValEnum><PropName>DTSTART</PropName><PropName>DTEND</PropName><PropName>DTSTAMP</PropName><PropName>SEQUENCE</PropName>'.
#'<PropName>END</PropName><ValEnum>VCALENDAR</ValEnum><ValEnum>VEVENT</ValEnum><ValEnum>VTODO</ValEnum><ValEnum>VALARM</ValEnum>'.
#'<PropName>UID</PropName><PropName>SUMMARY</PropName><PropName>VERSION</PropName><ValEnum>2.0</ValEnum><PropName>CATEGORIES</PropName>'.
#'<PropName>CLASS</PropName><PropName>DALARM</PropName><PropName>EXDATE</PropName><PropName>RESOURCES</PropName><PropName>STATUS</PropName>'.
#'<PropName>ATTACH</PropName><PropName>ATTENDEE</PropName><PropName>DCREATED</PropName><PropName>COMPLETED</PropName><PropName>DESCRIPTION'.
#'</PropName><PropName>DUE</PropName><PropName>LAST-MODIFIED</PropName><PropName>LOCATION</PropName><PropName>PRIORITY</PropName>'.
#'<PropName>RELATED-TO</PropName><PropName>TRANSP</PropName><PropName>URL</PropName><PropName>RRULE</PropName><PropName>COMMMENT</PropName>'.
#'<PropName>ACTION</PropName><PropName>TRIGGER</PropName><PropName>DURATION</PropName><PropName>REPEAT</PropName></CTCap><CTCap>'.
#
#'<CTType>text/x-vcard</CTType><PropName>BEGIN</PropName><ValEnum>VCARD</ValEnum><PropName>END</PropName><ValEnum>VCARD</ValEnum><PropName>'.
#'VERSION</PropName><ValEnum>2.1</ValEnum><PropName>ENCODING</PropName><PropName>VALUE</PropName><PropName>CHARSET</PropName>'.
#'<PropName>FN</PropName><PropName>N</PropName><PropName>NAME</PropName><PropName>NICKNAME</PropName><PropName>PHOTO</PropName>'.
#'<PropName>BDAY</PropName><PropName>ADR</PropName><PropName>LABEL</PropName><PropName>TEL</PropName><PropName>EMAIL</PropName>'.
#'<PropName>MAILER</PropName><PropName>TZ</PropName><PropName>GEO</PropName><PropName>TITLE</PropName><PropName>ROLE</PropName>'.
#'<PropName>LOGO</PropName><PropName>AGENT</PropName><PropName>ORG</PropName><PropName>CATEGORIES</PropName><PropName>NOTE</PropName>'.
#'<PropName>PRODID</PropName><PropName>REV</PropName><PropName>SORT-STRING</PropName><PropName>SOUND</PropName><PropName>URL</PropName>'.
#'<PropName>UID</PropName><PropName>CLASS</PropName><PropName>KEY</PropName></CTCap></DevInf>');
/**
* 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 &lt;(R|T)x-Pref&gt;&lt;CTType&gt;
* @param string $version: data for &lt;(R|T)x-Pref&gt;&lt;VerCT&gt;
* @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);
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 = '<![CDATA['.$this->_content.']]>';
#$chars = '<![CDATA['.$this->_content.']]>';
$chars = $this->_content;
$output->characters($chars);
$output->endElement($state->getURI(), 'Data');
}

View File

@ -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 <SyncML xmlns="syncml:SYNCML1.1"> element. They require
* just <SyncML>. 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

View File

@ -63,12 +63,12 @@ define('CHARSET_UTF_16LE', 'UTF-16LE');
define('CHARSET_UTF_16', 'UTF-16');
/**
* Copyright 2003-2005 Anthony Mills <amills@pyramid6.com>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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,

View File

@ -1,8 +1,8 @@
<?php
/**
* $Horde: framework/XML_WBXML/WBXML/ContentHandler.php,v 1.11 2005/01/20 00:01:19 jan Exp $
* $Horde: framework/XML_WBXML/WBXML/ContentHandler.php,v 1.15 2006/01/01 21:10:25 jan Exp $
*
* Copyright 2003-2005 Anthony Mills <amills@pyramid6.com>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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 = '<?xml version="1.0" encoding="UTF-8" ?>';
}
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()

View File

@ -1,11 +1,11 @@
<?php
/**
* $Horde: framework/XML_WBXML/WBXML/DTD.php,v 1.7 2005/01/03 13:09:25 jan Exp $
* $Horde: framework/XML_WBXML/WBXML/DTD.php,v 1.8 2006/01/01 21:10:25 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 <amills@pyramid6.com>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.

View File

@ -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 <amills@pyramid6.com>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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');

View File

@ -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 <amills@pyramid6.com>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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');
}
}

View File

@ -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 <amills@pyramid6.com>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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
}
}

View File

@ -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 <amills@pyramid6.com>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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;
}
}

View File

@ -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 <amills@pyramid6.com>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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 <data> 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 {
}
}

View File

@ -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 <amills@pyramid6.com>
* Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
*
* 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);
}
}