[sync] New patch...

Anthony Mills amills at gascard.net
Sat Dec 20 03:08:29 PST 2003


Here is a new patch, my last one did not go through.  This contains some code
for SyncML, mostly the SyncHdr tag.  I'll also include the command files.  I
have not finished converting the Sync commands, and it is not tested, but it
might be a few days before I can add some more.

Let me know how I can make this better,

Anthony
-------------- next part --------------
? RPC.patch
? XML_WBXML.patch
? rpc.tar
? syncml.patch.txt
? RPC/RPC/RPC.php
? RPC/RPC/stream_seg_fault_test.txt
? RPC/RPC/syncml.patch
? RPC/RPC/syncml.patch.txt
? RPC/RPC/syncml_command
? RPC/RPC/syncml_old.php
? RPC/RPC/syncml_state.php
? RPC/RPC/syncml_sync
? RPC/RPC/test.php
? XML_WBXML/WBXML/Decoder_old.php
? XML_WBXML/WBXML/Encoder_old.php
Index: RPC/package.xml
===================================================================
RCS file: /repository/framework/RPC/package.xml,v
retrieving revision 1.4
diff -u -r1.4 package.xml
--- RPC/package.xml	17 Dec 2003 15:42:48 -0000	1.4
+++ RPC/package.xml	20 Dec 2003 11:04:24 -0000
@@ -38,6 +38,7 @@
         <file name="syncml.php"/>
         <file name="syncml_wbxml.php"/>
         <file name="xmlrpc.php"/>
+        <file name="syncml_wbxml.php"/>
       </dir>
       <file role="test" name="tests/rpc-test.php"/>
     </filelist>
Index: RPC/RPC/syncml.php
===================================================================
RCS file: /repository/framework/RPC/RPC/syncml.php,v
retrieving revision 1.6
diff -u -r1.6 syncml.php
--- RPC/RPC/syncml.php	17 Dec 2003 16:02:44 -0000	1.6
+++ RPC/RPC/syncml.php	20 Dec 2003 11:04:24 -0000
@@ -1,21 +1,31 @@
 <?php
+
+include_once 'Horde/RPC/syncml_state.php';
+
 /**
  * The Horde_RPC_syncml class provides a SyncML implementation of the
  * Horde RPC system.
  *
  * $Horde: framework/RPC/RPC/syncml.php,v 1.6 2003/12/17 16:02:44 chuck Exp $
  *
- * Copyright 2003 Chuck Hagenbuch <chuck at horde.org>
+ * Copyright 2003 Chuck Hagenbuch <chuck at horde.org>, Anthony Mills <amills at 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 at horde.org>
+ * @author  Anthony Mills <amills at pyramid6.com>
  * @version $Revision: 1.6 $
  * @since   Horde 3.0
  * @package Horde_RPC
  */
-class Horde_RPC_syncml extends Horde_RPC {
+ 
+ /**
+  * All variables are from the client standpoint.
+  *
+  *
+  */
+class Horde_RPC_syncml_state {
 
     /**
      * Output ContentHandler used to output XML events.
@@ -31,7 +41,30 @@
     /**
      * Debug directory, if set will output packets
      */
-    var $_debugDir = '/tmp';
+    var $_debugDir = '/tmp/sync';
+
+    /**
+     * Debug directory, if set will output packets
+     */
+    var $_charset = 'UTF-8';
+
+    var $_contentHandler;
+    
+    var $_sourceURI;
+
+    var $_locName;
+
+    var $_sessionID;
+
+    var $_version;
+
+    var $_msgID;
+
+    var $_targetURI;
+
+    var $_currentCmdID;    
+
+    var $_isAuthorized = true;
 
     /**
      * SyncML handles authentication internally, so bypass the
@@ -39,6 +72,8 @@
      */
     function authorize()
     {
+        //authorizer is handled by the syncml server, always return true
+        
         return true;
     }
 
@@ -49,7 +84,7 @@
      *
      * @return string   The XML encoded response from the server.
      */
-    function getResponse($request)
+    function getResponse($xmloutput) //was $request
     {
         // Used for debugging.
         static $packetNum = -1;
@@ -58,7 +93,7 @@
         // Very useful for debugging.
         if (isset($this->_debugDir)) {
             $f = fopen($this->_debugDir . DIRECTORY_SEPARATOR . 'syncml_client_' . $packetNum . '.xml', 'wb');
-            fwrite($f, $request);
+            fwrite($f, $xmloutput);
             fclose($f);
         }
 
@@ -70,23 +105,23 @@
             $this->_output = &new XML_WBXML_ContentHandler();
         }
 
-        $this->_parse($request);
-        $response = $this->_output->getOutput();
+        $this->_parse($xmloutput);
+        $xmlinput = $this->_output->getOutput();
 
         // Very useful for debugging.
         if (isset($this->_debugDir)) {
             $f = fopen($this->_debugDir . DIRECTORY_SEPARATOR . 'syncml_server_' . $packetNum . '.xml', 'wb');
-            fwrite($f, $response);
+            fwrite($f, $xmlinput);
             fclose($f);
         }
 
-        return $response;
+        return $xmlinput;
     }
 
     function _parse($xml)
     {
         // Create the XML parser and set method references.
-        $this->_parser = xml_parser_create_ns($this->charset);
+        $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');
@@ -130,51 +165,326 @@
         return array($uri, $name);
     }
 
+    /**
+     * Get the Content-Type of the response.
+     *
+     * @return string  The MIME Content-Type of the RPC response.
+     */
+    function getResponseContentType()
+    {
+        return 'application/vnd.syncml+xml';
+    }
+
+    function getCharset()
+    {
+        return _charset;
+    }
+    
+    function getState($sourceURI, $locName, $sessionID)
+    {
+        
+    }
+
     function startElement($uri, $element, $attrs)
     {
+        $this->_xmlStack++;
+        
         switch ($this->_xmlStack) {
-        case 0:
+        case 1:
             if ($element == 'SyncML') {
                 $this->_output->startElement($uri, 'SyncML', $attrs);
             }
             break;
+        case 2:
+            if ($element == 'SyncHdr') {
+                $this->_contentHandler = &new Horde_RPC_SyncmlHdr();
+                $this->_contentHandler->setOutput($this->_output);
+            } else if ($element == 'SyncBody') {
+                $this->_contentHandler = &new Horde_RPC_SyncmlBody();
+                $this->_contentHandler->setOutput($this->_output);
+            }
+            break;
+        default:
+            if (isset($this->_contentHandler)) {
+                    $this->_contentHandler->startElement($uri, $element, $attrs);
+            }
+            break
         }
 
-        $this->_xmlStack++;
     }
 
     function endElement($uri, $element)
     {
-        $this->_xmlStack--;
-
         switch ($this->_xmlStack) {
-        case 0:
+        case 1:
             if ($element == 'SyncML') {
                 $this->_output->endElement($uri, 'SyncML');
             }
             break;
+        case 2:
+            if ($element = 'SyncHdr') {
+                $this->_currentState = getState($this->_sourceURI, $this->_locName, $this->_sessionID);
+                
+                $prevIsAuthorized = $this->_currentState->isAuthorized();
+                
+                $this->_currentState->setVersion($this->_version);
+                //$currentState->setIsAuthorized($this->_isAuthorized);
+                $this->_currentState->setMsgID($this->_msgID);
+                
+                $this->_currentState->setTargetURI($this->_targetURI);
+                
+                $attrs = array();                
+                $this->_output->startElement((($this->_version == 0) ? NAME_SPACE_URI_SYNCML : NAME_SPACE_URI_SYNCML_1_1), "SyncML", $attrs);
+
+                $this->_currentState->outputHeader($this->_output);
+                    //send status is okay
+/*
+ <SyncBody>
+  <Status>
+   <CmdID>
+    1
+   </CmdID>
+   <MsgRef>
+    1
+   </MsgRef>
+   <CmdRef>
+    0
+   </CmdRef>
+   <Cmd>
+    SyncHdr
+   </Cmd>
+   <TargetRef>
+    http://pyramid6.com:8080/sync
+   </TargetRef>
+   <SourceRef>
+    PocketPCwithoutSerial
+   </SourceRef>
+   <Chal>
+    <Meta>
+     <Format xmlns="syncml:metinf">
+      b64
+     </Format>
+     <Type xmlns="syncml:metinf">
+      syncml:auth-md5
+     </Type>
+     <NextNonce xmlns="syncml:metinf">
+      VyshXSMkISE=
+     </NextNonce>
+    </Meta>
+   </Chal>
+   <Data>
+    401
+   </Data>
+  </Status>
+*/
+                      
+                    $this->_output->startElement((($this->_version == 0) ? NAME_SPACE_URI_SYNCML : NAME_SPACE_URI_SYNCML_1_1), "SyncBody", $attrs);
+                    
+                    $status = new Status((prevIsAuthorized) ? RESPONSE_OK : RESPONSE_AUTHENTICATION_ACCEPTED, "SyncHdr");                    
+                    $status->setVersion($this->_version);
+                    $status->setIsAuthorized($this->_isAuthorized);
+                    $status->setMsgID($this->_msgID);
+                    
+                    $status->setTargetRef($this->_sourceURI);
+                    $status->setSourceRef($this->_targetURI);
+                    
+                    $this->_currentCmdID = status.output($this->_currentCmdID, $this->_output);                    
+                    
+                } else if ($element = 'SyncBody') {
+                    unset($this->_contentHandler)
+                    
+                    $this->output->endElement((($this->_version == 0) ? NAME_SPACE_URI_SYNCML : NAME_SPACE_URI_SYNCML_1_1), "SyncBody");
+                    $this->output->endElement((($this->_version == 0) ? NAME_SPACE_URI_SYNCML : NAME_SPACE_URI_SYNCML_1_1), "SyncML");                            
+                }
+                break;
+*/                
+            }
+            break;
+        //case 1:
+            //no need to do anything
+            //break;
+        default:
+            if (isset($this->_contentHandler)) {
+                    $this->_contentHandler->endElementImpl($uri, $element);
+            }
+            break
         }
 
         if (isset($this->_chars)) {
             unset($this->_chars);
         }
+        
+        $this->_xmlStack--;
     }
 
     function characters($str)
     {
-        if (isset($this->_chars)) {
-            $this->_chars = $this->_chars . $str;
+        if (isset($this->_contentHandler)) {
+            $this->_contentHandler->characters($str);
+        } else {
+            if (isset($this->_chars)) {
+                $this->_chars = $this->_chars . $str;
+            }
         }
     }
 
+}
+
+class Horde_RPC_SyncMLContentHandler {
     /**
-     * Get the Content-Type of the response.
-     *
-     * @return string  The MIME Content-Type of the RPC response.
+     * Output ContentHandler used to output XML events.
+     * @var object $_output
      */
-    function getResponseContentType()
+    var $_output;
+
+    /**
+     * @var integer $_xmlStack
+     */
+    var $_xmlStack = 1;
+
+    var $_charset = 'UTF-8';
+
+    var $_contentHandler;
+
+    function setOutput($output)
     {
-        return 'application/vnd.syncml+xml';
+        $this->_output = $output;
+    }
+
+    function startElement($uri, $element, $attrs)
+    {
+        $this->_xmlStack++;
+
+        if (isset($this->_contentHandler)) {
+            $this->_contentHandler->startElement($uri, $element, $attrs);
+        }
+    }
+
+    function endElement($uri, $element)
+    {
+        if (isset($this->_contentHandler)) {
+            $this->_contentHandler->endElement($uri, $element);
+        } else {
+            $this->endElement($uri, $element);
+        }
+
+        if (isset($this->_chars)) {
+            unset($this->_chars);
+        }
+        
+        $this->_xmlStack--;
+
+    }
+
+    function characters($str)
+    {
+        if (isset($this->_contentHandler)) {
+            $this->_contentHandler->characters($str);
+        } else {
+            if (isset($this->_chars)) {
+                $this->_chars = $this->_chars . $str;
+            }
+        }
+    }
+    
+}
+
+
+class Horde_RPC_SyncMLHdr extends Horde_RPC_SyncMLContentHandler {
+
+    var $_isSource = false;
+
+    var $_sourceURI;
+
+    var $_locName;
+
+    var $_sessionID;
+
+    var $_version;
+
+    var $_msgID;
+
+    var $_targetURI;
+
+    function startElement($uri, $element, $attrs) {
+        parent::startElement($uri, $element, $attrs);
+        
+        switch ($this->_xmlStack) {
+        case 3:
+            if ($element == 'Source')) {
+                $this->_isSource = true;
+            }
+            break;
+        }            
+    }
+
+    function endElement($uri, $element) {
+        switch ($this->_xmlStack) {
+            case 3:                    
+                if ($element == 'VerProto') {
+                    $this->_version = trim('SyncML/1.1')) ? 1 : 0;
+                } else if ($element == 'SessionID') {
+                   $this->_sessionID = trim($this->_chars);
+                } else if ($element == 'MsgID') {
+                   $this->_msgID = intval(trim($this->_chars));
+                }
+                break;
+            case 4:                
+                if ($elemet == 'LocURI') {
+                    if ($this->_isSource)
+                        $this->_sourceURI = trim($this->_chars);
+                    else
+                        $this->_targetURI = trim($this->_chars);
+                } else if ($elemet == 'LocName') {
+                    if ($this->_isSource)
+                        $this->_locName = trim($this->_chars);
+                }
+                break;                
+        }
+
+        parent::endElement($uri, $element);
+    }
+    
+    function getSourceURI() {
+        return $this->_sourceURI;
+    }
+
+    function getLocName() {
+        return $this->_locName;
+    }
+
+    function getSessionID() {
+        return $this->_sessionID;
+    }
+
+    function getVersion() {
+        return $this->_version;
+    }
+
+    function getMsgID() {
+        return $this->_msgID;
     }
 
+    function getTargetURI() {
+        return $this->_targetURI;
+    }
 }
+
+class Horde_RPC_SyncMLBody extends Horde_RPC_SyncMLContentHandler {
+    
+    function startElement($uri, $element, $attrs) {
+        parent::startElement($uri, $element, $attrs);
+        
+        
+        
+    }
+
+    function endElement($uri, $element) {
+        
+        
+        
+        parent::endElement($uri, $element);
+    }
+
+}
+
Index: RPC/RPC/syncml_wbxml.php
===================================================================
RCS file: /repository/framework/RPC/RPC/syncml_wbxml.php,v
retrieving revision 1.4
diff -u -r1.4 syncml_wbxml.php
--- RPC/RPC/syncml_wbxml.php	17 Dec 2003 16:03:32 -0000	1.4
+++ RPC/RPC/syncml_wbxml.php	20 Dec 2003 11:04:25 -0000
@@ -10,12 +10,13 @@
  *
  * $Horde: framework/RPC/RPC/syncml_wbxml.php,v 1.4 2003/12/17 16:03:32 chuck Exp $
  *
- * Copyright 2003 Chuck Hagenbuch <chuck at horde.org>
+ * Copyright 2003 Chuck Hagenbuch <chuck at horde.org>, Anthony Mills <amills at 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 at horde.org>
+ * @author  Anthony Mills <amills at pyramid6.com>
  * @version $Revision: 1.4 $
  * @since   Horde 3.0
  * @package Horde_RPC
@@ -23,25 +24,13 @@
 class Horde_RPC_syncml_wbxml extends Horde_RPC_syncml {
 
     /**
-     * The WBXML decoder wants to work on a filehandle, so instead of
-     * passing back a raw string, pass back a filehandle to the raw
-     * POST data.
-     *
-     * @return resource  Handle to the raw POST data.
-     */
-    function getInput()
-    {
-        return fopen('php://input', 'rb');
-    }
-
-    /**
      * Sends an RPC request to the server and returns the result.
      *
      * @param string    The raw request string.
      *
      * @return string   The WBXML encoded response from the server (binary).
      */
-    function getResponse($request)
+    function getResponse($wbxmlinput) // is normaly request $request
     {
         // Used for debugging.
         static $packetNum = -1;
@@ -50,38 +39,30 @@
         // Very useful for debugging.
         if (isset($this->_debugDir)) {
             $fp = fopen($this->_debugDir . DIRECTORY_SEPARATOR . 'syncml_client_' . $packetNum . '.wbxml', 'wb');
-            fwrite($fp, file_get_contents($request));
+            fwrite($fp, $wbxmlinput);
             fclose($fp);
         }
 
         $decoder = &new XML_WBXML_Decoder();
-        $xml = $decoder->decode($request);
-
-        if (is_a($xml, 'PEAR_Error')) {
-            Horde::logMessage($xml, __FILE__, __LINE__, PEAR_LOG_ERR);
+        $xmlinput = $decoder->decode($wbxmlinput);//wbxmlinput
+        if (is_a($xmlinput, 'PEAR_Error')) {
             return '';
         }
 
-        $GLOBALS['_wbxml'] = '';
-        $fp = fopen('gvar://_wbxml', 'wb');
+        $xmloutput = parent::getResponse($xmlinput);
 
         $encoder = &new XML_WBXML_Encoder();
-        $encoder->setOutputStream($fp);
         $encoder->setVersion($decoder->getVersion());
-        $encoder->setCharset($decoder->getCharset());
-        $encoder->encode($xml);
-
-        fclose($fp);
-        $wbxml = $GLOBALS['_wbxml'];
+        $encoder->setCharset($decoder->getCharsetStr());
+        $wbxmloutput = $encoder->encode($xmloutput);
 
-        // Very useful for debugging.
         if (isset($this->_debugDir)) {
             $fp = fopen($this->_debugDir . DIRECTORY_SEPARATOR . 'syncml_server_' . $packetNum . '.wbxml', 'wb');
-            fwrite($fp, $wbxml);
+            fwrite($fp, $wbxmloutput);
             fclose($fp);
         }
 
-        return $wbxml;
+        return $wbxmloutput;
     }
 
     /**
@@ -96,88 +77,3 @@
 
 }
 
-/**
- * Streams wrapper to allow encoding to a variable instead of to a
- * filehandle. From
- * http://www.php.net/manual/en/function.stream-wrapper-register.php.
- *
- * @package Horde_RPC
- */
-class Horde_RPC_GlobalVariableStream {
-
-    var $_position;
-    var $_varname;
-
-    function stream_open($path, $mode, $options, &$opened_path)
-    {
-        $url = parse_url($path);
-        $this->_varname = $url['host'];
-        $this->_position = 0;
-
-        return true;
-    }
-
-    function stream_read($count)
-    {
-        $ret = substr($GLOBALS[$this->_varname], $this->_position, $count);
-        $this->_position += strlen($ret);
-        return $ret;
-    }
-
-    function stream_write($data)
-    {
-        $left = substr($GLOBALS[$this->_varname], 0, $this->_position);
-        $right = substr($GLOBALS[$this->_varname], $this->_position + strlen($data));
-        $GLOBALS[$this->_varname] = $left . $data . $right;
-        $this->_position += strlen($data);
-        return strlen($data);
-    }
-
-    function stream_tell()
-    {
-        return $this->_position;
-    }
-
-    function stream_eof()
-    {
-        return $this->_position >= strlen($GLOBALS[$this->_varname]);
-    }
-
-    function stream_seek($offset, $whence)
-    {
-        switch ($whence) {
-        case SEEK_SET:
-            if ($offset < strlen($GLOBALS[$this->_varname]) && $offset >= 0) {
-                $this->_position = $offset;
-                return true;
-            } else {
-                return false;
-            }
-            break;
-
-        case SEEK_CUR:
-            if ($offset >= 0) {
-                $this->_position += $offset;
-                return true;
-            } else {
-                return false;
-            }
-            break;
-
-        case SEEK_END:
-            if (strlen($GLOBALS[$this->_varname]) + $offset >= 0) {
-                $this->_position = strlen($GLOBALS[$this->_varname]) + $offset;
-                return true;
-            } else {
-                return false;
-            }
-            break;
-
-        default:
-            return false;
-        }
-    }
-
-}
-
-stream_wrapper_register('gvar', 'Horde_RPC_GlobalVariableStream');
Index: XML_WBXML/WBXML.php
===================================================================
RCS file: /repository/framework/XML_WBXML/WBXML.php,v
retrieving revision 1.10
diff -u -r1.10 WBXML.php
--- XML_WBXML/WBXML.php	18 Dec 2003 00:32:59 -0000	1.10
+++ XML_WBXML/WBXML.php	20 Dec 2003 11:04:25 -0000
@@ -79,23 +79,23 @@
      *
      * Use long because it is unsigned.
      */
-    function MBUInt32ToInt($in)
+    function MBUInt32ToInt($in, &$pos)
     {
         $val = 0;
 
         do {
-            $b = ord(fread($in, 1));
+            $b = ord($in[$pos++]);
             $val <<= 7; // Bitshift left 7 bits.
             $val += ($b & 127);
         } while (($b & 128) != 0);
 
-        return $value;
+        return $val;
     }
 
     /**
      * Encoding Multi-byte Integers from Section 5.1
      */
-    function intToMBUInt32($out, $i)
+    function intToMBUInt32(&$out, $i)
     {
         if ($i > 268435455) {
             $bytes0 = 0 | XML_WBXML::getBits(0, $i);
@@ -104,39 +104,39 @@
             $bytes3 = 128 | XML_WBXML::getBits(3, $i);
             $bytes4 = 128 | XML_WBXML::getBits(4, $i);
 
-            fwrite($out, chr($bytes4));
-            fwrite($out, chr($bytes3));
-            fwrite($out, chr($bytes2));
-            fwrite($out, chr($bytes1));
-            fwrite($out, chr($bytes0));
+            $out .= chr($bytes4);
+            $out .= chr($bytes3);
+            $out .= chr($bytes2);
+            $out .= chr($bytes1);
+            $out .= 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);
 
-            fwrite($out, chr($bytes3));
-            fwrite($out, chr($bytes2));
-            fwrite($out, chr($bytes1));
-            fwrite($out, chr($bytes0));
+            $out .= chr($bytes3);
+            $out .= chr($bytes2);
+            $out .= chr($bytes1);
+            $out .= 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);
 
-            fwrite($out, chr($bytes2));
-            fwrite($out, chr($bytes1));
-            fwrite($out, chr($bytes0));
+            $out .= chr($bytes2);
+            $out .= chr($bytes1);
+            $out .= chr($bytes0);
         } elseif ($i > 127) {
             $bytes0 = 0 | XML_WBXML::getBits(0, $i);
             $bytes1 = 128 | XML_WBXML::getBits(1, $i);
 
-            fwrite($out, chr($bytes1));
-            fwrite($out, chr($bytes0));
+            $out .= chr($bytes1);
+            $out .= chr($bytes0);
         } else {
             $bytes0 = 0 | XML_WBXML::getBits(0, $i);
 
-            fwrite($out, chr($bytes0));
+            $out .= chr($bytes0);
         }
     }
 
Index: XML_WBXML/WBXML/ContentHandler.php
===================================================================
RCS file: /repository/framework/XML_WBXML/WBXML/ContentHandler.php,v
retrieving revision 1.4
diff -u -r1.4 ContentHandler.php
--- XML_WBXML/WBXML/ContentHandler.php	17 Dec 2003 16:01:21 -0000	1.4
+++ XML_WBXML/WBXML/ContentHandler.php	20 Dec 2003 11:04:25 -0000
@@ -40,7 +40,7 @@
         return PEAR::raiseError($error);
     }
 
-    function getCharset()
+    function getCharsetStr()
     {
         return $this->_charset;
     }
Index: XML_WBXML/WBXML/Decoder.php
===================================================================
RCS file: /repository/framework/XML_WBXML/WBXML/Decoder.php,v
retrieving revision 1.14
diff -u -r1.14 Decoder.php
--- XML_WBXML/WBXML/Decoder.php	17 Dec 2003 16:04:16 -0000	1.14
+++ XML_WBXML/WBXML/Decoder.php	20 Dec 2003 11:04:25 -0000
@@ -59,6 +59,13 @@
      * @var object XML_WBXML_DTDManager $dtdManager
      */
     var $_dtdManager;
+    
+    
+    /**
+     * The string position.
+     * @var integer string position
+     */
+    var $_strpos;
 
     /**
      * Constructor.
@@ -73,11 +80,12 @@
      */
     function getByte($input)
     {
-        return ord(fread($input, 1));
+        return ord($input[$this->_strpos++]);
     }
 
     function decode($input)
     {
+        $this->_strpos = 0;
         // Get Version Number from Section 5.4
         // version = u_int8
         // currently 1, 2 or 3
@@ -120,7 +128,7 @@
 
         $this->_attributeDTD = $this->_tagDTD;
 
-        while (!feof($input)) {
+        while ($this->_strpos < strlen($input)) {
             $this->_decode($input);
         }
 
@@ -137,7 +145,7 @@
         // 'dpiType' 'dpiNumber'
         $dpistruct = array();
 
-        $i = XML_WBXML::MBUInt32ToInt($input);
+        $i = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
 
         if ($i == 0) {
             $dpiStruct['dpiType'] = 2;
@@ -167,7 +175,7 @@
      */
     function getCharset($input)
     {
-        $cs = XML_WBXML::MBUInt32ToInt($input);
+        $cs = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
         return $charset = XML_WBXML::getCharsetString($cs);
     }
 
@@ -178,7 +186,7 @@
     function getStringTable($input, $cs)
     {
         $stringTable = array();
-        $size = XML_WBXML::MBUInt32ToInt($input);
+        $size = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
 
         // A hack to make it work with arrays.
         // How/why is this necessary?
@@ -190,7 +198,7 @@
         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 = fread($input, 1);
+            $ch = $input[$this->_strpos++];
             if (ord($ch) == 0) {
                 $stringTable[$numstr++] = $str;
                 $str = '#';
@@ -252,7 +260,7 @@
         case XML_WBXML_GLOBAL_TOKEN_ENTITY:
             // Section 5.8.4.3
             // UCS-4 chracter encoding?
-            $entity = $this->entity(XML_WBXML::MBUInt32ToInt($input));
+            $entity = $this->entity(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
 
             $this->_ch->characters('&#' . $entity . ';');
             break;
@@ -264,33 +272,33 @@
 
         case XML_WBXML_GLOBAL_TOKEN_LITERAL:
             // Section 5.8.4.5
-            $str = $this->_stringTable[XML_WBXML::MBUInt32ToInt($input)];
+            $str = $this->_stringTable[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)];
+            $str = $this->_stringTable[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)];
+            $str = $this->_stringTable[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)];
+            $str = $this->_stringTable[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);
-            $b = fread($input, $size);
-
+            $size = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
+            $b = substr($input, $this->_strpos, $this->_strpos + $size);
+            $this->_strpos += $size;
             $this->_ch->opaque($b);
 
             // FIXME Opaque is used by SYNCML.  Opaque data that depends on the context
@@ -393,7 +401,7 @@
                                      'value' => $value);
                 }
 
-                $attr = $this->_stringTable[XML_WBXML::MBUInt32ToInt($input)];
+                $attr = $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
                 break;
 
             // Value specified.
@@ -408,19 +416,19 @@
             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)];
+                $value .= $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
                 break;
 
             case XML_WBXML_GLOBAL_TOKEN_EXT_0:
             case XML_WBXML_GLOBAL_TOKEN_EXT_1:
             case XML_WBXML_GLOBAL_TOKEN_EXT_2:
                 // Section 5.8.4.2
-                $value .= fread($input, 1);
+                $value .= $input[$this->_strpos++];
                 break;
 
             case XML_WBXML_GLOBAL_TOKEN_ENTITY:
                 // Section 5.8.4.3
-                $value .= $this->entity(XML_WBXML::MBUInt32ToInt($input));
+                $value .= $this->entity(XML_WBXML::MBUInt32ToInt($input, $this->_strpos));
                 break;
 
             case XML_WBXML_GLOBAL_TOKEN_STR_I:
@@ -430,13 +438,14 @@
 
             case XML_WBXML_GLOBAL_TOKEN_STR_T:
                 // Section 5.8.4.1
-                $value .= $this->_stringTable[XML_WBXML::MBUInt32ToInt($input)];
+                $value .= $this->_stringTable[XML_WBXML::MBUInt32ToInt($input, $this->_strpos)];
                 break;
 
             case XML_WBXML_GLOBAL_TOKEN_OPAQUE:
                 // Section 5.8.4.6
-                $size = XML_WBXML::MBUInt32ToInt($input);
-                $b = fread($input, $size);
+                $size = XML_WBXML::MBUInt32ToInt($input, $this->_strpos);
+                $b = substr($input, $this->_strpos, $this->_strpos + $size);
+                $this->_strpos += $size;
 
                 $value .= $b;
                 break;
@@ -545,10 +554,10 @@
     {
         $str = '#';
         $i = 0;
-        $ch = fread($input, 1);
+        $ch = $input[$this->_strpos++];
         while (ord($ch) != 0) {
             $str[$i++] = $ch;
-            $ch = fread($input, 1);
+            $ch = $input[$this->_strpos++];
         }
 
         return $str;
Index: XML_WBXML/WBXML/Encoder.php
===================================================================
RCS file: /repository/framework/XML_WBXML/WBXML/Encoder.php,v
retrieving revision 1.15
diff -u -r1.15 Encoder.php
--- XML_WBXML/WBXML/Encoder.php	17 Dec 2003 16:10:32 -0000	1.15
+++ XML_WBXML/WBXML/Encoder.php	20 Dec 2003 11:04:25 -0000
@@ -28,7 +28,7 @@
 
     var $_dtd;
 
-    var $_outputStream;
+    var $_output;
 
     var $_uris = array();
 
@@ -64,23 +64,21 @@
     /**
      * Constructor.
      */
-    function XML_WBXML_Encoder($outputStream = null)
+    function XML_WBXML_Encoder()
     {
-        if ($outputStream) {
-            $this->setOutputStream($outputStream);
-        }
-
         $this->_stringTable = &new XML_WBXML_HashTable();
         $this->_dtdManager = &new XML_WBXML_DTDManager();
         $this->_hasWrittenHeader = false;
 
         $this->_subParser = null;
         $this->_subParserStack = 0;
+        
+        $this->_output = '';
     }
 
     /**
      * Take the input $xml and turn it into WBXML, which gets sent to
-     * $this->_outputStream.
+     * $this->_output.
      */
     function encode($xml)
     {
@@ -101,12 +99,14 @@
         }
 
         xml_parser_free($this->_parser);
+        
+        return $this->_output;
     }
 
     /**
      * This will write the correct headers.
      */
-    function writeHeader($out, $uri)
+    function writeHeader($uri)
     {
         $this->_dtd = &$this->_dtdManager->getInstanceURI($uri);
 
@@ -115,58 +115,58 @@
         // Set Version Number from Section 5.4
         // version = u_int8
         // currently 1, 2 or 3
-        $this->writeVersionNumber($out, $this->_wbxmlVersion);
+        $this->writeVersionNumber($this->_wbxmlVersion);
 
         // Set 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.
-        $this->writeDocumentPublicIdentifier($out, $dpiString, $this->_strings);
+        $this->writeDocumentPublicIdentifier($dpiString, $this->_strings);
 
         // Set Charset from 5.6
         // charset = mb_u_int32
-        $this->writeCharset($out, $this->_charset);
+        $this->writeCharset($this->_charset);
 
         // Set String Table from 5.7
         // strb1 = length *byte
-        $this->writeStringTable($out, $this->_strings, $this->_charset, $this->_stringTable);
+        $this->writeStringTable($this->_strings, $this->_charset, $this->_stringTable);
 
         $this->_currentURI = $uri;
 
         $this->_hasWrittenHeader = true;
     }
 
-    function writeVersionNumber($out, $version)
+    function writeVersionNumber($version)
     {
-        fwrite($out, chr($version));
+        $this->_output.= chr($version);
     }
 
-    function writeDocumentPublicIdentifier($out, $dpiString, &$strings)
+    function writeDocumentPublicIdentifier($dpiString, &$strings)
     {
         $i = XML_WBXML::getDPIInt($dpiString);
 
         if ($i == 0) {
             $strings[0] = $dpiString;
-            fwrite($out, chr(0));
-            fwrite($out, chr(0));
+            $this->_output .= chr(0);
+            $this->_output .= chr(0);
         } else {
-            XML_WBXML::intToMBUInt32($out, $i);
+            XML_WBXML::intToMBUInt32($this->_output, $i);
         }
     }
 
-    function writeCharset($out, $charset)
+    function writeCharset($charset)
     {
         $cs = XML_WBXML::getCharsetInt($charset);
 
         if ($cs == 0) {
             return $this->raiseError('Unsupported Charset: ' . $charset);
         } else {
-            XML_WBXML::intToMBUInt32($out, $cs);
+            XML_WBXML::intToMBUInt32($this->_output, $cs);
         }
     }
 
-    function writeStringTable($out, $strings, $charset, $stringTable)
+    function writeStringTable($strings, $charset, $stringTable)
     {
         $stringBytes = array();
         $count = 0;
@@ -178,20 +178,20 @@
             $count += count($bytes) + $nullLength;
         }
 
-        XML_WBXML::intToMBUInt32($out, count($stringBytes));
-        fwrite($out, implode('', $stringBytes));
+        XML_WBXML::intToMBUInt32($this->_output, count($stringBytes));
+        $this->_output.= implode('', $stringBytes);
     }
 
-    function writeString($out, $str, $cs)
+    function writeString($str, $cs)
     {
         $bytes = $this->_getBytes($str, $cs);
-        fwrite($out, implode('', $bytes));
-        $this->writeNull($out, $cs);
+        $this->_output.= implode('', $bytes);
+        $this->writeNull($cs);
     }
 
-    function writeNull($out, $charset)
+    function writeNull($charset)
     {
-        fwrite($out, chr(0));
+        $this->_output.= chr(0);
         return 1;
     }
 
@@ -228,21 +228,21 @@
     function startEndElementImp($uri, $name, $attributes)
     {
         if (!$this->_hasWrittenHeader) {
-            $this->writeHeader($this->_outputStream, $uri);
+            $this->writeHeader($uri);
         }
 
-        $this->writeTag($this->_outputStream, $name, $attributes, false, $this->_charset);
+        $this->writeTag($name, $attributes, false, $this->_charset);
     }
 
     function startElementImp($uri, $name, $attributes)
     {
         if (!$this->_hasWrittenHeader) {
-            $this->writeHeader($this->_outputStream, $uri);
+            $this->writeHeader($uri);
         }
 
         $this->pushCurrentURI($uri);
 
-        $this->writeTag($this->_outputStream, $name, $attributes, true, $this->_charset);
+        $this->writeTag($name, $attributes, true, $this->_charset);
     }
 
     function writeStartElement($isEnd)
@@ -284,9 +284,9 @@
         if ($this->_subParser == null) {
             $this->writeStartElement(false);
 
-            fwrite($this->_outputStream, chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE));
-            XML_WBXML::intToMBUInt32($this->_outputStream, count($bytes));
-            fwrite($this->_outputStream, $bytes);
+            $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE);
+            XML_WBXML::intToMBUInt32($this->_output, count($bytes));
+            $this->_output .= $bytes;
         }
     }
 
@@ -301,11 +301,11 @@
 
                 $i = $this->_stringTable->get($chars);
                 if ($i != null) {
-                    fwrite($this->_outputStream, chr(XML_WBXML_GLOBAL_TOKEN_STR_T));
-                    XML_WBXML::intToMBUInt32($this->_outputStream, $i);
+                    $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_T);
+                    XML_WBXML::intToMBUInt32($this->_output, $i);
                 } else {
-                    fwrite($this->_outputStream, chr(XML_WBXML_GLOBAL_TOKEN_STR_I));
-                    $this->writeString($this->_outputStream, $chars, $this->_charset);
+                    $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_I);
+                    $this->writeString($chars, $this->_charset);
                 }
             }
         }
@@ -320,7 +320,7 @@
     {
     }
 
-    function writeTag($out, $name, $attrs, $hasContent, $cs)
+    function writeTag($name, $attrs, $hasContent, $cs)
     {
         if ($attrs != null && !count($attrs)) {
             $attrs = null;
@@ -333,44 +333,44 @@
                 return $this->raiseError($name . ' is not found in String Table or DTD');
             } else {
                 if ($attrs == null && !$hasContent) {
-                    fwrite($out, chr(XML_WBXML_GLOBAL_TOKEN_LITERAL));
+                    $this->_output.= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL);
                 } elseif ($attrs == null && $hasContent) {
-                    fwrite($out, chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_A));
+                    $this->_output.= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_A);
                 } elseif ($attrs != null && $hasContent) {
-                    fwrite($out, chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_C));
+                    $this->_output.= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_C);
                 } elseif ($attrs != null && !$hasContent) {
-                    fwrite($out, chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_AC));
+                    $this->_output.= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_AC);
                 }
 
-                XML_WBXML::intToMBUInt32($out, $i);
+                XML_WBXML::intToMBUInt32($this->_output, $i);
             }
         } else {
             if ($attrs == null && !$hasContent) {
-                fwrite($out, chr($t));
+                $this->_output.= chr($t);
             } elseif ($attrs == null && $hasContent) {
-                fwrite($out, chr($t | 64));
+                $this->_output.= chr($t | 64);
             } elseif ($attrs != null && $hasContent) {
-                fwrite($out, chr($t | 128));
+                $this->_output.= chr($t | 128);
             } elseif ($attrs != null && !$hasContent) {
-                fwrite($out, chr($t | 192));
+                $this->_output.= chr($t | 192);
             }
         }
 
         if ($attrs != null) {
-            $this->writeAttributes($out, $attrs, $cs);
+            $this->writeAttributes($attrs, $cs);
         }
     }
 
-    function writeAttributes($out, $attrs, $cs)
+    function writeAttributes($attrs, $cs)
     {
         foreach ($attrs as $name => $value) {
-            $this->writeAttribute($out, $name, $value, $cs);
+            $this->writeAttribute($name, $value, $cs);
         }
 
-        fwrite($out, chr(XML_WBXML_GLOBAL_TOKEN_END));
+        $this->_output.= chr(XML_WBXML_GLOBAL_TOKEN_END);
     }
 
-    function writeAttribute($out, $name, $value, $cs)
+    function writeAttribute($name, $value, $cs)
     {
         $a = $this->_dtd->toAttribute($name);
         if ($a == -1) {
@@ -378,20 +378,20 @@
             if ($i == null) {
                 return $this->raiseError($name . ' is not found in String Table or DTD');
             } else {
-                fwrite($out, chr(XML_WBXML_GLOBAL_TOKEN_LITERAL));
-                XML_WBXML::intToMBUInt32($out, $i);
+                $this->_output.= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL);
+                XML_WBXML::intToMBUInt32($this->_output, $i);
             }
         } else {
-            fwrite($out, $a);
+            $this->_output.= $a;
         }
 
         $i = $this->_stringTable->get($name);
         if ($i != null) {
-            fwrite($out, chr(XML_WBXML_GLOBAL_TOKEN_STR_T));
-            XML_WBXML::intToMBUInt32($out, $i);
+            $this->_output.= chr(XML_WBXML_GLOBAL_TOKEN_STR_T);
+            XML_WBXML::intToMBUInt32($this->_output, $i);
         } else {
-            fwrite($out, chr(XML_WBXML_GLOBAL_TOKEN_STR_I));
-            $this->writeString($out, $value, $cs);
+            $this->_output.= chr(XML_WBXML_GLOBAL_TOKEN_STR_I);
+            $this->writeString($value, $cs);
         }
     }
 
@@ -400,7 +400,7 @@
         if ($this->_subParser == null) {
             $this->writeStartElement(false);
             $this->popCurrentURI();
-            fwrite($this->_outputStream, chr(XML_WBXML_GLOBAL_TOKEN_END));
+            $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_END);
         } else {
             $this->_subParserStack--;
             if ($this->_subParserStack == 0) {
@@ -452,13 +452,13 @@
         if (strlen($cp)) {
             $this->_dtd = &$this->_dtdManager->getInstanceURI($uri);
 
-            fwrite($this->_outputStream, chr(XML_WBXML_GLOBAL_TOKEN_SWITCH_CODE_PAGE));
-            fwrite($this->_outputStream, chr($cp));
+            $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_SWITCH_CODE_PAGE);
+            $this->_output .= chr($cp);
 
         } else {
-            fwrite($this->_outputStream, chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE));
+            $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE);
 
-            $this->_subParser = &new XML_WBXML_Encoder($this->_outputStream);
+            $this->_subParser = &new XML_WBXML_Encoder($this->_output);
             $this->startElement($this->_storeURI, $this->_storeName, $this->_storeAttributes);
 
             $this->_subParserStack = 2;
@@ -470,12 +470,12 @@
     }
 
     /**
-     * Setter for property outputStream.
-     * @param outputStream New value of property outputStream.
+     * Getter for property output.
      */
-    function setOutputStream($outputStream)
+    function getOutput($output)
     {
-        $this->_outputStream = $outputStream;
+        return $this->_output;
     }
 
 }
+


More information about the sync mailing list