[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/phpgwapi/inc/horde/XML/WBXML/ -> Encoder.php (source)

   1  <?php
   2  
   3  include_once 'XML/WBXML.php';
   4  include_once 'XML/WBXML/ContentHandler.php';
   5  include_once 'XML/WBXML/DTDManager.php';
   6  include_once 'Horde/String.php';
   7  
   8  /**
   9   * $Horde: framework/XML_WBXML/WBXML/Encoder.php,v 1.39 2006/01/01 21:10:25 jan Exp $
  10   *
  11   * Copyright 2003-2006 Anthony Mills <amills@pyramid6.com>
  12   *
  13   * See the enclosed file COPYING for license information (LGPL).  If you
  14   * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  15   *
  16   * From Binary XML Content Format Specification Version 1.3, 25 July
  17   * 2001 found at http://www.wapforum.org
  18   *
  19   * @package XML_WBXML
  20   */
  21  class XML_WBXML_Encoder extends XML_WBXML_ContentHandler {
  22  
  23      var $_strings = array();
  24  
  25      var $_stringTable;
  26  
  27      var $_hasWrittenHeader = false;
  28  
  29      var $_dtd;
  30  
  31      var $_output = '';
  32  
  33      var $_uris = array();
  34  
  35      var $_uriNums = array();
  36  
  37      var $_currentURI;
  38  
  39      var $_subParser = null;
  40      var $_subParserStack = 0;
  41      
  42      /**
  43       * The XML parser.
  44       *
  45       * @var resource
  46       */
  47      var $_parser;
  48  
  49      /**
  50       * The DTD Manager.
  51       *
  52       * @var XML_WBXML_DTDManager
  53       */
  54      var $_dtdManager;
  55  
  56      /**
  57       * Constructor.
  58       */
  59      function XML_WBXML_Encoder()
  60      {
  61          $this->_dtdManager = &new XML_WBXML_DTDManager();
  62          $this->_stringTable = &new XML_WBXML_HashTable();
  63      }
  64  
  65      /**
  66       * Take the input $xml and turn it into WBXML. This is _not_ the
  67       * intended way of using this class. It is derived from
  68       * Contenthandler and one should use it as a ContentHandler and
  69       * produce the XML-structure with startElement(), endElement(),
  70       * and characters().
  71       */
  72      function encode($xml)
  73      {
  74          // Create the XML parser and set method references.
  75          $this->_parser = xml_parser_create_ns($this->_charset);
  76          xml_set_object($this->_parser, $this);
  77          xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
  78          xml_set_element_handler($this->_parser, '_startElement', '_endElement');
  79          xml_set_character_data_handler($this->_parser, '_characters');
  80          xml_set_processing_instruction_handler($this->_parser, '');
  81          xml_set_external_entity_ref_handler($this->_parser, '');
  82  
  83          if (!xml_parse($this->_parser, $xml)) {
  84              return $this->raiseError(sprintf('XML error: %s at line %d',
  85                                               xml_error_string(xml_get_error_code($this->_parser)),
  86                                               xml_get_current_line_number($this->_parser)));
  87          }
  88  
  89          xml_parser_free($this->_parser);
  90  
  91          return $this->_output;
  92      }
  93  
  94      /**
  95       * This will write the correct headers.
  96       */
  97      function writeHeader($uri)
  98      {
  99          $this->_dtd = &$this->_dtdManager->getInstanceURI($uri);
 100  
 101          $dpiString = $this->_dtd->getDPI();
 102  
 103          // Set Version Number from Section 5.4
 104          // version = u_int8
 105          // currently 1, 2 or 3
 106          $this->writeVersionNumber($this->_wbxmlVersion);
 107  
 108          // Set Document Public Idetifier from Section 5.5
 109          // publicid = mb_u_int32 | ( zero index )
 110          // zero = u_int8
 111          // containing the value zero (0)
 112          // The actual DPI is determined after the String Table is read.
 113          $this->writeDocumentPublicIdentifier($dpiString, $this->_strings);
 114  
 115          // Set Charset from 5.6
 116          // charset = mb_u_int32
 117          $this->writeCharset($this->_charset);
 118  
 119          // Set String Table from 5.7
 120          // strb1 = length *byte
 121          $this->writeStringTable($this->_strings, $this->_charset, $this->_stringTable);
 122  
 123          $this->_currentURI = $uri;
 124  
 125          $this->_hasWrittenHeader = true;
 126      }
 127  
 128      function writeVersionNumber($version)
 129      {
 130          $this->_output .= chr($version);
 131      }
 132  
 133      function writeDocumentPublicIdentifier($dpiString, &$strings)
 134      {
 135          $i = XML_WBXML::getDPIInt($dpiString);
 136  
 137          if ($i == 0) {
 138              $strings[0] = $dpiString;
 139              $this->_output .= chr(0);
 140              $this->_output .= chr(0);
 141          } else {
 142              XML_WBXML::intToMBUInt32($this->_output, $i);
 143          }
 144      }
 145  
 146      function writeCharset($charset)
 147      {
 148          $cs = XML_WBXML::getCharsetInt($charset);
 149  
 150          if ($cs == 0) {
 151              return $this->raiseError('Unsupported Charset: ' . $charset);
 152          } else {
 153              XML_WBXML::intToMBUInt32($this->_output, $cs);
 154          }
 155      }
 156  
 157      function writeStringTable($strings, $charset, $stringTable)
 158      {
 159          $stringBytes = array();
 160          $count = 0;
 161          foreach ($strings as $str) {
 162              $bytes = $this->_getBytes($str, $charset);
 163              $stringBytes = array_merge($stringBytes, $bytes);
 164              $nullLength = $this->_addNullByte($bytes);
 165              $this->_stringTable->set($str, $count);
 166              $count += count($bytes) + $nullLength;
 167          }
 168  
 169          XML_WBXML::intToMBUInt32($this->_output, count($stringBytes));
 170          $this->_output .= implode('', $stringBytes);
 171      }
 172  
 173      function writeString($str, $cs)
 174      {
 175          $bytes = $this->_getBytes($str, $cs);
 176          $this->_output .= implode('', $bytes);
 177          $this->writeNull($cs);
 178      }
 179  
 180      function writeNull($charset)
 181      {
 182          $this->_output .= chr(0);
 183          return 1;
 184      }
 185  
 186      function _addNullByte(&$bytes)
 187      {
 188          $bytes[] = chr(0);
 189          return 1;
 190      }
 191  
 192      function _getBytes($string, $cs)
 193      {
 194          $string = String::convertCharset($string, $cs, 'utf-8');
 195          $nbytes = strlen($string);
 196  
 197          $bytes = array();
 198          for ($i = 0; $i < $nbytes; $i++) {
 199              $bytes[] = $string{$i};
 200          }
 201  
 202          return $bytes;
 203      }
 204  
 205      function _splitURI($tag)
 206      {
 207          $parts = explode(':', $tag);
 208          $name = array_pop($parts);
 209          $uri = implode(':', $parts);
 210          return array($uri, $name);
 211      }
 212  
 213      function startElement($uri, $name, $attributes)
 214      {
 215          if ($this->_subParser == null) {
 216              if (!$this->_hasWrittenHeader) {
 217                  $this->writeHeader($uri);
 218              }
 219              if ($this->_currentURI != $uri) {
 220                  $this->changecodepage($uri);
 221              }
 222              if ($this->_subParser == null) {
 223                  $this->writeTag($name, $attributes, true, $this->_charset);
 224              } else {
 225                  $this->_subParser->startElement($uri,$name, $attributes);
 226              }
 227          } else {
 228              $this->_subParserStack++;
 229              $this->_subParser->startElement($uri,$name,$attributes);
 230          }
 231      }
 232  
 233      function _startElement($parser, $tag, $attributes)
 234      {
 235          list($uri, $name) = $this->_splitURI($tag);
 236  
 237          $this->startElement($uri, $name, $attributes);
 238      }
 239  
 240      function opaque($bytes)
 241      {
 242          if ($this->_subParser == null) {
 243              $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE);
 244              XML_WBXML::intToMBUInt32($this->_output, count($bytes));
 245              $this->_output .= $bytes;
 246          }
 247      }
 248  
 249      function characters($chars)
 250      {
 251          $chars = trim($chars);
 252  
 253          if (strlen($chars)) {
 254              /* We definitely don't want any whitespace. */
 255              if ($this->_subParser == null) {
 256                  $i = $this->_stringTable->get($chars);
 257                  if ($i != null) {
 258                      $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_T);
 259                      XML_WBXML::intToMBUInt32($this->_output, $i);
 260                  } else {
 261                      $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_I);
 262                      $this->writeString($chars, $this->_charset);
 263                  }
 264              } else {
 265                  $this->_subParser->characters($chars);
 266              }
 267          }
 268      }
 269  
 270      function _characters($parser, $chars)
 271      {
 272          $this->characters($chars);
 273      }
 274  
 275      function writeTag($name, $attrs, $hasContent, $cs)
 276      {
 277  
 278          if ($attrs != null && !count($attrs)) {
 279              $attrs = null;
 280          }
 281  
 282          $t = $this->_dtd->toTagInt($name);
 283          if ($t == -1) {
 284              $i = $this->_stringTable->get($name);
 285              if ($i == null) {
 286                  return $this->raiseError($name . ' is not found in String Table or DTD');
 287              } else {
 288                  if ($attrs == null && !$hasContent) {
 289                      $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL);
 290                  } elseif ($attrs == null && $hasContent) {
 291                      $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_A);
 292                  } elseif ($attrs != null && $hasContent) {
 293                      $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_C);
 294                  } elseif ($attrs != null && !$hasContent) {
 295                      $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_AC);
 296                  }
 297  
 298                  XML_WBXML::intToMBUInt32($this->_output, $i);
 299              }
 300          } else {
 301              if ($attrs == null && !$hasContent) {
 302                  $this->_output .= chr($t);
 303              } elseif ($attrs == null && $hasContent) {
 304                  $this->_output .= chr($t | 64);
 305              } elseif ($attrs != null && $hasContent) {
 306                  $this->_output .= chr($t | 128);
 307              } elseif ($attrs != null && !$hasContent) {
 308                  $this->_output .= chr($t | 192);
 309              }
 310          }
 311  
 312          if ($attrs != null && is_array($attrs) && count($attrs) > 0 ) {
 313              $this->writeAttributes($attrs, $cs);
 314          }
 315      }
 316  
 317      function writeAttributes($attrs, $cs)
 318      {
 319          foreach ($attrs as $name => $value) {
 320              $this->writeAttribute($name, $value, $cs);
 321          }
 322  
 323          $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_END);
 324      }
 325  
 326      function writeAttribute($name, $value, $cs)
 327      {
 328          $a = $this->_dtd->toAttribute($name);
 329          if ($a == -1) {
 330              $i = $this->_stringTable->get($name);
 331              if ($i == null) {
 332                  return $this->raiseError($name . ' is not found in String Table or DTD');
 333              } else {
 334                  $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL);
 335                  XML_WBXML::intToMBUInt32($this->_output, $i);
 336              }
 337          } else {
 338              $this->_output .= $a;
 339          }
 340  
 341          $i = $this->_stringTable->get($name);
 342          if ($i != null) {
 343              $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_T);
 344              XML_WBXML::intToMBUInt32($this->_output, $i);
 345          } else {
 346              $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_I);
 347              $this->writeString($value, $cs);
 348          }
 349      }
 350  
 351      function endElement($uri, $name)
 352      {
 353          if ($this->_subParser == null) {
 354              $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_END);
 355          } else {
 356              $this->_subParser->endElement($uri, $name);
 357              $this->_subParserStack--;
 358  
 359              if ($this->_subParserStack == 0) {
 360                  $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE);
 361  
 362                  XML_WBXML::intToMBUInt32($this->_output,
 363                                           strlen($this->_subParser->getOutput()));
 364                  $this->_output .= $this->_subParser->getOutput();
 365  
 366                  $this->_subParser = null;
 367              }
 368          }
 369      }
 370  
 371      function _endElement($parser, $tag)
 372      {
 373          list($uri, $name) = $this->_splitURI($tag);
 374          $this->endElement($uri, $name);
 375      }
 376  
 377      function changecodepage($uri)
 378      {
 379          // @todo: this is a hack!
 380          // what's the reason for this hack???? Lars
 381          if ($uri != 'syncml:devinf' && $uri != 'syncml:metinf' && $uri != 'syncml:syncml1.0' && !preg_match('/1\.1$/', $uri)) {
 382              $uri .= '1.1';
 383          }
 384          $cp = $this->_dtd->toCodePageURI($uri);
 385          if (strlen($cp)) {
 386              $this->_dtd = &$this->_dtdManager->getInstanceURI($uri);
 387  
 388              $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_SWITCH_PAGE);
 389              $this->_output .= chr($cp);
 390              $this->_currentURI = $uri;
 391  
 392          } else {
 393              $this->_subParser = &new XML_WBXML_Encoder(true);
 394              $this->_subParserStack = 1;
 395          }
 396      }
 397  
 398      /**
 399       * Getter for property output.
 400       */
 401      function getOutput()
 402      {
 403          return $this->_output;
 404      }
 405  
 406      function getOutputSize()
 407      {
 408          return strlen($this->_output);
 409      }
 410  
 411  }


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7