diff --git a/src/include/Syncroton/Wbxml/Abstract.php b/src/include/Syncroton/Wbxml/Abstract.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Abstract.php @@ -0,0 +1,256 @@ + + * @version $Id:Abstract.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Wbxml + */ + +abstract class Syncroton_Wbxml_Abstract +{ + /** + * stream containing the wbxml encoded data + * + * @var resource + */ + protected $_stream; + + /** + * the wbxml version + * + * @var string + */ + protected $_version; + + /** + * the Document Public Identifier + * + * @var string + */ + protected $_dpi; + + /** + * the current active dtd + * + * @var Syncroton_Wbxml_Dtd_Syncml_Abstract + */ + protected $_dtd; + + /** + * the charSet used in the wbxml file + * + * @var string + */ + protected $_charSet; + + /** + * currently active code page + * + * @var array + */ + protected $_codePage; + + /** + * see section 5.5 + * + */ + const DPI_WELLKNOWN = 'WELLKNOWN'; + + /** + * see section 5.5 + * + */ + const DPI_STRINGTABLE = 'STRINGTABLE'; + + const SWITCH_PAGE = 0x00; + const END = 0x01; + const ENTITY = 0x02; + const STR_I = 0x03; + const LITERAL = 0x04; + const EXT_I_0 = 0x40; + const EXT_I_1 = 0x41; + const EXT_I_2 = 0x42; + const PI = 0x43; + const LITERAL_C = 0x44; + const EXT_T_0 = 0x80; + const EXT_T_1 = 0x81; + const EXT_T_2 = 0x82; + const STR_T = 0x83; + const LITERAL_A = 0x84; + const EXT_0 = 0xC0; + const EXT_1 = 0xC1; + const EXT_2 = 0xC2; + const OPAQUE = 0xC3; + const LITERAL_AC = 0xC4; + + /** + * the real name for this DPI is "unknown" + * But Microsoft is using them for their ActiveSync stuff + * instead defining their own DPI like the sycnml creators did + * + */ + const DPI_1 = '-//AIRSYNC//DTD AirSync//EN'; + + /** + * return wellknown identifiers + * + * @param integer $_uInt + * @todo add well known identifiers from section 7.2 + * @return string + */ + public function getDPI($_uInt = 0) + { + if(!defined('Syncroton_Wbxml_Abstract::DPI_' . $_uInt)) { + throw new Syncroton_Wbxml_Exception('unknown wellknown identifier: ' . $_uInt); + } + + $dpi = constant('Syncroton_Wbxml_Abstract::DPI_' . $_uInt); + + return $dpi; + } + + /** + * return multibyte integer + * + * @return integer + */ + protected function _getMultibyteUInt() + { + $uInt = 0; + + do { + $byte = $this->_getByte(); + $uInt <<= 7; + $uInt += ($byte & 127); + } while (($byte & 128) != 0); + + return $uInt; + } + + protected function _getByte() + { + $byte = fread($this->_stream, 1); + + if($byte === false) { + throw new Syncroton_Wbxml_Exception("failed reading one byte"); + } + + return ord($byte); + } + + protected function _getOpaque($_length) + { + $string = ''; + + // it might happen that not complete data is read from stream. + // loop until all data is read or EOF + while ($_length) { + $chunk = fread($this->_stream, $_length); + + if ($chunk === false) { + throw new Syncroton_Wbxml_Exception("failed reading opaque data"); + } + + if ($len = strlen($chunk)) { + $string .= $chunk; + $_length -= $len; + } + + if (feof($this->_stream)) { + break; + } + } + + return $string; + } + + /** + * get a 0 terminated string + * + * @return string + */ + protected function _getTerminatedString() + { + $string = ''; + + while (($byte = $this->_getByte()) != 0) { + $string .= chr($byte); + } + + return $string; + } + + protected function _writeByte($_byte) + { + fwrite($this->_stream, chr($_byte)); + } + + protected function _writeMultibyteUInt($_integer) + { + $multibyte = NULL; + $remainder = $_integer; + + do { + $byte = ($remainder & 127); + $remainder >>= 7; + if($multibyte === NULL) { + $multibyte = chr($byte); + } else { + $multibyte = chr($byte | 128) . $multibyte; + } + } while ($remainder != 0); + + fwrite($this->_stream, $multibyte); + } + + protected function _writeString($_string) + { + fwrite($this->_stream, $_string); + } + + /** + * write opaque string to stream + * + * @param string|resource $_string + * @throws Syncroton_Wbxml_Exception + */ + protected function _writeOpaqueString($_string) + { + if (is_resource($_string)) { + $stream = $_string; + } else { + $stream = fopen("php://temp", 'r+'); + fwrite($stream, $_string); + } + $length = ftell($stream); + rewind($stream); + + $this->_writeByte(Syncroton_Wbxml_Abstract::OPAQUE); + $this->_writeMultibyteUInt($length); + $writenBytes = stream_copy_to_stream($stream, $this->_stream); + + if($writenBytes !== $length) { + throw new Syncroton_Wbxml_Exception('blow'); + } + + fclose($stream); + } + + protected function _writeTerminatedString($_string) + { + $this->_writeByte(Syncroton_Wbxml_Abstract::STR_I); + fwrite($this->_stream, $_string); + fwrite($this->_stream, chr(0)); + } +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Decoder.php b/src/include/Syncroton/Wbxml/Decoder.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Decoder.php @@ -0,0 +1,306 @@ + + * @version $Id:Decoder.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class to convert WBXML to XML + * + * @package Wbxml + * @subpackage Wbxml + */ + +class Syncroton_Wbxml_Decoder extends Syncroton_Wbxml_Abstract +{ + /** + * type of Document Public Identifier + * + * @var string the type can be Syncroton_Wbxml_Abstract::DPI_STRINGTABLE or Syncroton_Wbxml_Abstract::DPI_WELLKNOWN + */ + protected $_dpiType; + + /** + * the string table + * + * @var array + */ + protected $_stringTable = array(); + + /** + * the xml document + * + * @var DOMDocument + */ + protected $_dom; + + /** + * the main name space / aka the namespace of first tag + * + * @var string + */ + protected $_mainNameSpace; + + /** + * the constructor will try to read all data until the first tag + * + * @param resource $_stream + */ + public function __construct($_stream, $_dpi = NULL) + { + if(!is_resource($_stream) || get_resource_type($_stream) != 'stream') { + throw new Syncroton_Wbxml_Exception('$_stream must be a stream'); + } + if($_dpi !== NULL) { + $this->_dpi = $_dpi; + } + + $this->_stream = $_stream; + + $this->_version = $this->_getByte(); + + if(feof($this->_stream)) { + throw new Syncroton_Wbxml_Exception_UnexpectedEndOfFile(); + } + + $this->_getDPI(); + + $this->_getCharset(); + + $this->_getStringTable(); + + // resolve DPI as we have read the stringtable now + // this->_dpi contains the string table index + if($this->_dpiType === Syncroton_Wbxml_Abstract::DPI_STRINGTABLE) { + $this->_dpi = $this->_stringTable[$this->_dpi]; + } + + #$this->_dtd = Syncroton_Wbxml_Dtd_Factory::factory($this->_dpi); + $this->_dtd = Syncroton_Wbxml_Dtd_Factory::factory(Syncroton_Wbxml_Dtd_Factory::ACTIVESYNC); + } + + /** + * return the Document Public Identifier + * + * @param integer $_uInt unused param, needed to satisfy abstract class method signature + * @return string + */ + public function getDPI($_uInt = 0) + { + return $this->_dpi; + } + + /** + * return the wbxml version + * + * @return string + */ + public function getVersion() + { + return $this->_version; + } + + /** + * decodes the tags + * + * @return DOMDocument the decoded xml + */ + public function decode() + { + $openTags = NULL; + $node = NULL; + $this->_codePage = $this->_dtd->getCurrentCodePage(); + + while (!feof($this->_stream)) { + $byte = $this->_getByte(); + + switch($byte) { + case Syncroton_Wbxml_Abstract::END: + $node = $node->parentNode; + $openTags--; + break; + + case Syncroton_Wbxml_Abstract::OPAQUE: + $length = $this->_getMultibyteUInt(); + if($length > 0) { + $opaque = $this->_getOpaque($length); + try { + // let see if we can decode it. maybe the opaque data is wbxml encoded content + $opaqueDataStream = fopen("php://temp", 'r+'); + fputs($opaqueDataStream, $opaque); + rewind($opaqueDataStream); + + $opaqueContentDecoder = new Syncroton_Wbxml_Decoder($opaqueDataStream); + $dom = $opaqueContentDecoder->decode(); + + fclose($opaqueDataStream); + + foreach($dom->childNodes as $newNode) { + if($newNode instanceof DOMElement) { + $newNode = $this->_dom->importNode($newNode, true); + $node->appendChild($newNode); + } + } + } catch (Exception $e) { + // if not, just treat it as a string + $node->appendChild($this->_dom->createTextNode($opaque)); + } + } + break; + + case Syncroton_Wbxml_Abstract::STR_I: + $string = $this->_getTerminatedString(); + $node->appendChild($this->_dom->createTextNode($string)); + break; + + case Syncroton_Wbxml_Abstract::SWITCH_PAGE: + $page = $this->_getByte(); + $this->_codePage = $this->_dtd->switchCodePage($page); + #echo "switched to codepage $page\n"; + break; + + default: + $tagHasAttributes = (($byte & 0x80) != 0); + $tagHasContent = (($byte & 0x40) != 0); + // get rid of bit 7+8 + $tagHexCode = $byte & 0x3F; + + try { + $tag = $this->_codePage->getTag($tagHexCode); + } catch (Syncroton_Wbxml_Exception $swe) { + // tag can not be converted to ASCII name + $tag = sprintf('unknown tag 0x%x', $tagHexCode); + } + $nameSpace = $this->_codePage->getNameSpace(); + $codePageName = $this->_codePage->getCodePageName(); + + #echo "Tag: $nameSpace:$tag\n"; + + if ($node === NULL) { + // create the domdocument + $node = $this->_createDomDocument($nameSpace, $tag); + $newNode = $node->documentElement; + } else { + if (!$this->_dom->isDefaultNamespace($nameSpace)) { + $this->_dom->documentElement->setAttribute('xmlns:' . $codePageName, $nameSpace); + } + $newNode = $node->appendChild($this->_dom->createElementNS('uri:' . $codePageName, $tag)); + } + + if ($tagHasAttributes) { + $attributes = $this->_getAttributes(); + } + + if ($tagHasContent == true) { + $node = $newNode; + $openTags++; + } + + break; + } + } + + return $this->_dom; + } + + /** + * creates the root of the xml document + * + * @return DOMDocument + */ + protected function _createDomDocument($_nameSpace, $_tag) + { + $this->_dom = $this->_dtd->getDomDocument($_nameSpace, $_tag); + + return $this->_dom; + } + + /** + * read the attributes of the current tag + * + * @todo implement logic + */ + protected function _getAttributes() + { + die("fetching attributes not yet implemented!\n"); + } + + /** + * get document public identifier + * + * the identifier can be all welknown identifier (see section 7.2) or a string from the stringtable + */ + protected function _getDPI() + { + $uInt = $this->_getMultibyteUInt(); + + if($uInt == 0) { + // get identifier from stringtable + $this->_dpiType = Syncroton_Wbxml_Abstract::DPI_STRINGTABLE; + // string table identifier, can be resolved only after reading string table + $this->_dpi = $this->_getByte(); + } else { + // wellknown identifier + $this->_dpiType = Syncroton_Wbxml_Abstract::DPI_WELLKNOWN; + $this->_dpi = Syncroton_Wbxml_Abstract::getDPI($uInt); + } + } + + /** + * see http://www.iana.org/assignments/character-sets (MIBenum) + * 106: UTF-8 + * + */ + protected function _getCharset() + { + $uInt = $this->_getMultibyteUInt(); + + switch($uInt) { + case 106: + $this->_charSet = 'UTF-8'; + break; + + default: + throw new Syncroton_Wbxml_Exception('unsuported charSet: ' . $uInt); + break; + } + } + + /** + * get string table and store strings indexed by start + * + * @todo validate spliting at 0 value + */ + protected function _getStringTable() + { + $length = $this->_getMultibyteUInt(); + + if($length > 0) { + $rawStringTable = $this->_getOpaque($length); + $index = NULL; + $string = NULL; + + for($i = 0; $i < strlen($rawStringTable); $i++) { + if($index === NULL) { + $index = $i; + } + if(ord($rawStringTable[$i]) != 0) { + $string .= $rawStringTable[$i]; + } + + // either the string has ended or we reached a \0 + if($i+1 == strlen($rawStringTable) || ord($rawStringTable[$i]) == 0){ + $this->_stringTable[$index] = $string; + $index = NULL; + $string = NULL; + } + } + } + } +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync.php new file mode 100755 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync.php @@ -0,0 +1,110 @@ + + * @version $Id:Factory.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync +{ + const CODEPAGE_AIRSYNC = 0; + const CODEPAGE_CONTACTS = 1; + const CODEPAGE_EMAIL = 2; + const CODEPAGE_AIRNOTIFY = 3; + const CODEPAGE_CALENDAR = 4; + const CODEPAGE_MOVE = 5; + const CODEPAGE_ITEMESTIMATE = 6; + const CODEPAGE_FOLDERHIERARCHY = 7; + const CODEPAGE_MEETINGRESPONSE = 8; + const CODEPAGE_TASKS = 9; + const CODEPAGE_RESOLVERECIPIENTS = 10; + const CODEPAGE_VALIDATECERT = 11; + const CODEPAGE_CONTACTS2 = 12; + const CODEPAGE_PING = 13; + const CODEPAGE_PROVISION = 14; + const CODEPAGE_SEARCH = 15; + const CODEPAGE_GAL = 16; + const CODEPAGE_AIRSYNCBASE = 17; + const CODEPAGE_SETTINGS = 18; + const CODEPAGE_DOCUMENTLIBRARY = 19; + const CODEPAGE_ITEMOPERATIONS = 20; + const CODEPAGE_COMPOSEMAIL = 21; + const CODEPAGE_EMAIL2 = 22; + const CODEPAGE_NOTES = 23; + const CODEPAGE_RIGHTSMANAGEMENT = 24; + + /** + * variable to hold currently active codepage + * + * @var Syncroton_Wbxml_Dtd_ActiveSync_Abstract + */ + protected $_currentCodePage; + + /** + * the constructor + * + */ + public function __construct() + { + $this->_currentCodePage = new Syncroton_Wbxml_Dtd_ActiveSync_CodePage0(); + } + + /** + * returns reference to current codepage + * + * @return Syncroton_Wbxml_Dtd_ActiveSync_Abstract + */ + public function getCurrentCodePage() + { + return $this->_currentCodePage; + } + + /** + * switch to another codepage + * + * @param integer $_codePageId id of the codepage + * @return Syncroton_Wbxml_Dtd_ActiveSync_Abstract + */ + public function switchCodePage($_codePageId) + { + $className = 'Syncroton_Wbxml_Dtd_ActiveSync_CodePage' . $_codePageId; + + $this->_currentCodePage = new $className(); + + return $this->_currentCodePage; + } + + /** + * get initial dom document + * + * @return DOMDocument + */ + public function getDomDocument($_nameSpace, $_tag) + { + // Creates an instance of the DOMImplementation class + $imp = new DOMImplementation(); + + // Creates a DOMDocumentType instance + $dtd = $imp->createDocumentType('AirSync', "-//AIRSYNC//DTD AirSync//EN", "http://www.microsoft.com/"); + + // Creates a DOMDocument instance + $dom = $imp->createDocument($_nameSpace, $_tag, $dtd); + + $dom->encoding = 'utf-8'; + $dom->formatOutput = false; + + return $dom; + } +} diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/Abstract.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/Abstract.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/Abstract.php @@ -0,0 +1,114 @@ + + * @version $Id:AirSync.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +abstract class Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + /** + * codepage number + * + * @var integer + */ + protected $_codePageNumber = NULL; + + /** + * codepage name + * + * @var string + */ + protected $_codePageName = NULL; + + /** + * document page identifier + * not needed for ActiveSync + * + * @var integer + */ + protected $_dpi = NULL; + + /** + * mapping of tags to id's + * + * @var array + */ + protected $_tags = array(); + + /** + * return document page identifier + * is always NULL for activesync + * + * @return unknown + */ + public function getDPI() + { + return $this->_dpi; + } + + /** + * get codepage name + * + * @return string + */ + public function getCodePageName() + { + return $this->_codePageName; + } + + /** + * get namespace identifier + * + * @return string + */ + public function getNameSpace() + { + return 'uri:' . $this->_codePageName; + } + + /** + * get tag identifier + * + * @param string $_tag the tag name + * @return integer + */ + public function getIdentity($_tag) + { + if(!isset($this->_tags[$_tag])) { + //var_dump($this->_tags); + throw new Syncroton_Wbxml_Exception("tag $_tag not found"); + } + + return $this->_tags[$_tag]; + } + + /** + * return tag by given identity + * + * @param unknown_type $_identity + * @return unknown + */ + public function getTag($_identity) + { + $tag = array_search($_identity, $this->_tags); + + if($tag === false) { + throw new Syncroton_Wbxml_Exception("identity $_identity not found"); + } + + return $tag; + } +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage0.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage0.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage0.php @@ -0,0 +1,64 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage0 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 0; + + protected $_codePageName = 'AirSync'; + + protected $_tags = array( + 'Sync' => 0x05, + 'Responses' => 0x06, + 'Add' => 0x07, + 'Change' => 0x08, + 'Delete' => 0x09, + 'Fetch' => 0x0a, + 'SyncKey' => 0x0b, + 'ClientId' => 0x0c, + 'ServerId' => 0x0d, + 'Status' => 0x0e, + 'Collection' => 0x0f, + 'Class' => 0x10, + 'Version' => 0x11, + 'CollectionId' => 0x12, + 'GetChanges' => 0x13, + 'MoreAvailable' => 0x14, + 'WindowSize' => 0x15, + 'Commands' => 0x16, + 'Options' => 0x17, + 'FilterType' => 0x18, + 'Truncation' => 0x19, + 'RtfTruncation' => 0x1a, + 'Conflict' => 0x1b, + 'Collections' => 0x1c, + 'ApplicationData' => 0x1d, + 'DeletesAsMoves' => 0x1e, + 'NotifyGUID' => 0x1f, + 'Supported' => 0x20, + 'SoftDelete' => 0x21, + 'MIMESupport' => 0x22, + 'MIMETruncation' => 0x23, + 'Wait' => 0x24, + 'Limit' => 0x25, + 'Partial' => 0x26, + 'ConversationMode' => 0x27, + 'MaxItems' => 0x28, + 'HeartbeatInterval' => 0x29 + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage1.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage1.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage1.php @@ -0,0 +1,85 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage1 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 1; + + protected $_codePageName = 'Contacts'; + + protected $_tags = array( + 'Anniversary' => 0x05, + 'AssistantName' => 0x06, + 'AssistantPhoneNumber' => 0x07, + 'Birthday' => 0x08, + 'Body' => 0x09, + 'BodySize' => 0x0a, + 'BodyTruncated' => 0x0b, + 'Business2PhoneNumber' => 0x0c, + 'BusinessAddressCity' => 0x0d, + 'BusinessAddressCountry' => 0x0e, + 'BusinessAddressPostalCode' => 0x0f, + 'BusinessAddressState' => 0x10, + 'BusinessAddressStreet' => 0x11, + 'BusinessFaxNumber' => 0x12, + 'BusinessPhoneNumber' => 0x13, + 'CarPhoneNumber' => 0x14, + 'Categories' => 0x15, + 'Category' => 0x16, + 'Children' => 0x17, + 'Child' => 0x18, + 'CompanyName' => 0x19, + 'Department' => 0x1a, + 'Email1Address' => 0x1b, + 'Email2Address' => 0x1c, + 'Email3Address' => 0x1d, + 'FileAs' => 0x1e, + 'FirstName' => 0x1f, + 'Home2PhoneNumber' => 0x20, + 'HomeAddressCity' => 0x21, + 'HomeAddressCountry' => 0x22, + 'HomeAddressPostalCode' => 0x23, + 'HomeAddressState' => 0x24, + 'HomeAddressStreet' => 0x25, + 'HomeFaxNumber' => 0x26, + 'HomePhoneNumber' => 0x27, + 'JobTitle' => 0x28, + 'LastName' => 0x29, + 'MiddleName' => 0x2a, + 'MobilePhoneNumber' => 0x2b, + 'OfficeLocation' => 0x2c, + 'OtherAddressCity' => 0x2d, + 'OtherAddressCountry' => 0x2e, + 'OtherAddressPostalCode' => 0x2f, + 'OtherAddressState' => 0x30, + 'OtherAddressStreet' => 0x31, + 'PagerNumber' => 0x32, + 'RadioPhoneNumber' => 0x33, + 'Spouse' => 0x34, + 'Suffix' => 0x35, + 'Title' => 0x36, + 'WebPage' => 0x37, + 'YomiCompanyName' => 0x38, + 'YomiFirstName' => 0x39, + 'YomiLastName' => 0x3a, + 'Rtf' => 0x3b, + 'Picture' => 0x3c, + 'Alias' => 0x3d, + 'WeightedRank' => 0x3e + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage10.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage10.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage10.php @@ -0,0 +1,52 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage10 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 10; + + protected $_codePageName = 'ResolveRecipients'; + + protected $_tags = array( + 'ResolveRecipients' => 0x05, + 'Response' => 0x06, + 'Status' => 0x07, + 'Type' => 0x08, + 'Recipient' => 0x09, + 'DisplayName' => 0x0a, + 'EmailAddress' => 0x0b, + 'Certificates' => 0x0c, + 'Certificate' => 0x0d, + 'MiniCertificate' => 0x0e, + 'Options' => 0x0f, + 'To' => 0x10, + 'CertificateRetrieval' => 0x11, + 'RecipientCount' => 0x12, + 'MaxCertificates' => 0x13, + 'MaxAmbiguousRecipients' => 0x14, + 'CertificateCount' => 0x15, + 'Availability' => 0x16, + 'StartTime' => 0x17, + 'EndTime' => 0x18, + 'MergedFreeBusy' => 0x19, + 'Picture' => 0x1a, + 'MaxSize' => 0x1b, + 'Data' => 0x1c, + 'MaxPictures' => 0x1d + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage11.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage11.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage11.php @@ -0,0 +1,33 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage11 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 11; + + protected $_codePageName = 'ValidateCert'; + + protected $_tags = array( + 'ValidateCert' => 0x05, + 'Certificates' => 0x06, + 'Certificate' => 0x07, + 'CertificateChain' => 0x08, + 'CheckCRL' => 0x09, + 'Status' => 0x0a + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage12.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage12.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage12.php @@ -0,0 +1,37 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage12 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 12; + + protected $_codePageName = 'Contacts2'; + + protected $_tags = array( + 'CustomerId' => 0x05, + 'GovernmentId' => 0x06, + 'IMAddress' => 0x07, + 'IMAddress2' => 0x08, + 'IMAddress3' => 0x09, + 'ManagerName' => 0x0a, + 'CompanyMainPhone' => 0x0b, + 'AccountName' => 0x0c, + 'NickName' => 0x0d, + 'MMS' => 0x0e + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage13.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage13.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage13.php @@ -0,0 +1,35 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage13 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 13; + + protected $_codePageName = 'Ping'; + + protected $_tags = array( + 'Ping' => 0x05, + 'AutdState' => 0x06, //unused + 'Status' => 0x07, + 'HeartbeatInterval' => 0x08, + 'Folders' => 0x09, + 'Folder' => 0x0a, + 'Id' => 0x0b, + 'Class' => 0x0c, + 'MaxFolders' => 0x0d + ); +} diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage14.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage14.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage14.php @@ -0,0 +1,82 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + * @todo add missing tags + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage14 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 14; + + protected $_codePageName = 'Provision'; + + protected $_tags = array( + 'Provision' => 0x05, + 'Policies' => 0x06, + 'Policy' => 0x07, + 'PolicyType' => 0x08, + 'PolicyKey' => 0x09, + 'Data' => 0x0a, + 'Status' => 0x0b, + 'RemoteWipe' => 0x0c, + 'EASProvisionDoc' => 0x0d, + 'DevicePasswordEnabled' => 0x0e, + 'AlphanumericDevicePasswordRequired' => 0x0f, + 'RequireStorageCardEncryption' => 0x10, + 'PasswordRecoveryEnabled' => 0x11, + 'DocumentBrowseEnabled' => 0x12, + 'AttachmentsEnabled' => 0x13, + 'MinDevicePasswordLength' => 0x14, + 'MaxInactivityTimeDeviceLock' => 0x15, + 'MaxDevicePasswordFailedAttempts' => 0x16, + 'MaxAttachmentSize' => 0x17, + 'AllowSimpleDevicePassword' => 0x18, + 'DevicePasswordExpiration' => 0x19, + 'DevicePasswordHistory' => 0x1a, + 'AllowStorageCard' => 0x1b, + 'AllowCamera' => 0x1c, + 'RequireDeviceEncryption' => 0x1d, + 'AllowUnsignedApplications' => 0x1e, + 'AllowUnsignedInstallationPackages' => 0x1f, + 'MinDevicePasswordComplexCharacters' => 0x20, + 'AllowWiFi' => 0x21, + 'AllowTextMessaging' => 0x22, + 'AllowPOPIMAPEmail' => 0x23, + 'AllowBluetooth' => 0x24, + 'AllowIrDA' => 0x25, + 'RequireManualSyncWhenRoaming' => 0x26, + 'AllowDesktopSync' => 0x27, + 'MaxCalendarAgeFilter' => 0x28, + 'AllowHTMLEmail' => 0x29, + 'MaxEmailAgeFilter' => 0x2a, + 'MaxEmailBodyTruncationSize' => 0x2b, + 'MaxEmailHTMLBodyTruncationSize' => 0x2c, + 'RequireSignedSMIMEMessages' => 0x2d, + 'RequireEncryptedSMIMEMessages' => 0x2e, + 'RequireSignedSMIMEAlgorithm' => 0x2F, + 'RequireEncryptionSMIMEAlgorithm' => 0x30, + 'AllowSMIMEEncryptionAlgorithmNegotiation' => 0x31, + 'AllowSMIMESoftCerts' => 0x32, + 'AllowBrowser' => 0x33, + 'AllowConsumerEmail' => 0x34, + 'AllowRemoteDesktop' => 0x35, + 'AllowInternetSharing' => 0x36, + 'UnapprovedInROMApplicationList' => 0x37, + 'ApplicationName' => 0x38, + 'ApprovedApplicationList' => 0x39, + 'Hash' => 0x3a, + ); +} diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage15.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage15.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage15.php @@ -0,0 +1,56 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage15 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 15; + + protected $_codePageName = 'Search'; + + protected $_tags = array( + 'Search' => 0x05, + 'Store' => 0x07, + 'Name' => 0x08, + 'Query' => 0x09, + 'Options' => 0x0a, + 'Range' => 0x0b, + 'Status' => 0x0c, + 'Response' => 0x0d, + 'Result' => 0x0e, + 'Properties' => 0x0f, + 'Total' => 0x10, + 'EqualTo' => 0x11, + 'Value' => 0x12, + 'And' => 0x13, + 'Or' => 0x14, + 'FreeText' => 0x15, + 'DeepTraversal' => 0x17, + 'LongId' => 0x18, + 'RebuildResults' => 0x19, + 'LessThan' => 0x1a, + 'GreaterThan' => 0x1b, + 'Schema' => 0x1c, + 'Supported' => 0x1d, + 'UserName' => 0x1e, + 'Password' => 0x1f, + 'ConversationId' => 0x20, + 'Picture' => 0x21, + 'MaxSize' => 0x22, + 'MaxPictures' => 0x23 + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage16.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage16.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage16.php @@ -0,0 +1,41 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage16 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 16; + + protected $_codePageName = 'GAL'; + + protected $_tags = array( + 'DisplayName' => 0x05, + 'Phone' => 0x06, + 'Office' => 0x07, + 'Title' => 0x08, + 'Company' => 0x09, + 'Alias' => 0x0a, + 'FirstName' => 0x0b, + 'LastName' => 0x0c, + 'HomePhone' => 0x0d, + 'MobilePhone' => 0x0e, + 'EmailAddress' => 0x0f, + 'Picture' => 0x10, + 'Status' => 0x11, + 'Data' => 0x12, + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage17.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage17.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage17.php @@ -0,0 +1,49 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage17 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 17; + + protected $_codePageName = 'AirSyncBase'; + + protected $_tags = array( + 'BodyPreference' => 0x05, + 'Type' => 0x06, + 'TruncationSize' => 0x07, + 'AllOrNone' => 0x08, + 'Body' => 0x0a, + 'Data' => 0x0b, + 'EstimatedDataSize' => 0x0c, + 'Truncated' => 0x0d, + 'Attachments' => 0x0e, + 'Attachment' => 0x0f, + 'DisplayName' => 0x10, + 'FileReference' => 0x11, + 'Method' => 0x12, + 'ContentId' => 0x13, + 'ContentLocation' => 0x14, + 'IsInline' => 0x15, + 'NativeBodyType' => 0x16, + 'ContentType' => 0x17, + 'Preview' => 0x18, + 'BodyPartReference' => 0x19, + 'BodyPart' => 0x1a, + 'Status' => 0x1b, + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage18.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage18.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage18.php @@ -0,0 +1,65 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage18 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 18; + + protected $_codePageName = 'Settings'; + + protected $_tags = array( + 'Settings' => 0x05, + 'Status' => 0x06, + 'Get' => 0x07, + 'Set' => 0x08, + 'Oof' => 0x09, + 'OofState' => 0x0a, + 'StartTime' => 0x0b, + 'EndTime' => 0x0c, + 'OofMessage' => 0x0d, + 'AppliesToInternal' => 0x0e, + 'AppliesToExternalKnown' => 0x0f, + 'AppliesToExternalUnknown' => 0x10, + 'Enabled' => 0x11, + 'ReplyMessage' => 0x12, + 'BodyType' => 0x13, + 'DevicePassword' => 0x14, + 'Password' => 0x15, + 'DeviceInformation' => 0x16, + 'Model' => 0x17, + 'IMEI' => 0x18, + 'FriendlyName' => 0x19, + 'OS' => 0x1a, + 'OSLanguage' => 0x1b, + 'PhoneNumber' => 0x1c, + 'UserInformation' => 0x1d, + 'EmailAddresses' => 0x1e, + 'SMTPAddress' => 0x1f, + 'UserAgent' => 0x20, + 'EnableOutboundSMS' => 0x21, + 'MobileOperator' => 0x22, + 'PrimarySmtpAddress' => 0x23, + 'Accounts' => 0x24, + 'Account' => 0x25, + 'AccountId' => 0x26, + 'AccountName' => 0x27, + 'UserDisplayName' => 0x28, + 'SendDisabled' => 0x29, + 'RightsManagementInformation' => 0x2b, + ); +} diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage19.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage19.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage19.php @@ -0,0 +1,35 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage19 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 19; + + protected $_codePageName = 'DocumentLibrary'; + + protected $_tags = array( + 'LinkId' => 0x05, + 'DisplayName' => 0x06, + 'IsFolder' => 0x07, + 'CreationDate' => 0x08, + 'LastModifiedDate' => 0x09, + 'IsHidden' => 0x0a, + 'ContentLength' => 0x0b, + 'ContentType' => 0x0c + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage2.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage2.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage2.php @@ -0,0 +1,86 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage2 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 2; + + protected $_codePageName = 'Email'; + + protected $_tags = array( + 'Attachment' => 0x05, + 'Attachments' => 0x06, + 'AttName' => 0x07, + 'AttSize' => 0x08, + 'Att0Id' => 0x09, + 'AttMethod' => 0x0a, + 'AttRemoved' => 0x0b, + 'Body' => 0x0c, + 'BodySize' => 0x0d, + 'BodyTruncated' => 0x0e, + 'DateReceived' => 0x0f, + 'DisplayName' => 0x10, + 'DisplayTo' => 0x11, + 'Importance' => 0x12, + 'MessageClass' => 0x13, + 'Subject' => 0x14, + 'Read' => 0x15, + 'To' => 0x16, + 'Cc' => 0x17, + 'From' => 0x18, + 'ReplyTo' => 0x19, + 'AllDayEvent' => 0x1a, + 'Categories' => 0x1b, + 'Category' => 0x1c, + 'DTStamp' => 0x1d, + 'EndTime' => 0x1e, + 'InstanceType' => 0x1f, + 'BusyStatus' => 0x20, + 'Location' => 0x21, + 'MeetingRequest' => 0x22, + 'Organizer' => 0x23, + 'RecurrenceId' => 0x24, + 'Reminder' => 0x25, + 'ResponseRequested' => 0x26, + 'Recurrences' => 0x27, + 'Recurrence' => 0x28, + 'Type' => 0x29, + 'Until' => 0x2a, + 'Occurrences' => 0x2b, + 'Interval' => 0x2c, + 'DayOfWeek' => 0x2d, + 'DayOfMonth' => 0x2e, + 'WeekOfMonth' => 0x2f, + 'MonthOfYear' => 0x30, + 'StartTime' => 0x31, + 'Sensitivity' => 0x32, + 'TimeZone' => 0x33, + 'GlobalObjId' => 0x34, + 'ThreadTopic' => 0x35, + 'MIMEData' => 0x36, + 'MIMETruncated' => 0x37, + 'MIMESize' => 0x38, + 'InternetCPID' => 0x39, + 'Flag' => 0x3a, + 'Status' => 0x3b, + 'ContentClass' => 0x3c, + 'FlagType' => 0x3d, + 'CompleteTime' => 0x3e, + 'DisallowNewTimeProposal' => 0x3f + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage20.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage20.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage20.php @@ -0,0 +1,48 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage20 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 20; + + protected $_codePageName = 'ItemOperations'; + + protected $_tags = array( + 'ItemOperations' => 0x05, + 'Fetch' => 0x06, + 'Store' => 0x07, + 'Options' => 0x08, + 'Range' => 0x09, + 'Total' => 0x0a, + 'Properties' => 0x0b, + 'Data' => 0x0c, + 'Status' => 0x0d, + 'Response' => 0x0e, + 'Version' => 0x0f, + 'Schema' => 0x10, + 'Part' => 0x11, + 'EmptyFolderContents' => 0x12, + 'DeleteSubFolders' => 0x13, + 'UserName' => 0x14, + 'Password' => 0x15, + 'Move' => 0x16, + 'DstFldId' => 0x17, + 'ConversationId' => 0x18, + 'MoveAlways' => 0x19, + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage21.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage21.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage21.php @@ -0,0 +1,41 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage21 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 21; + + protected $_codePageName = 'ComposeMail'; + + protected $_tags = array( + 'SendMail' => 0x05, + 'SmartForward' => 0x06, + 'SmartReply' => 0x07, + 'SaveInSentItems' => 0x08, + 'ReplaceMime' => 0x09, + 'Source' => 0x0b, + 'FolderId' => 0x0c, + 'ItemId' => 0x0d, + 'LongId' => 0x0e, + 'InstanceId' => 0x0f, + 'Mime' => 0x10, + 'ClientId' => 0x11, + 'Status' => 0x12, + 'AccountId' => 0x13, + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage22.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage22.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage22.php @@ -0,0 +1,42 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage22 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 22; + + protected $_codePageName = 'Email2'; + + protected $_tags = array( + 'UmCallerID' => 0x05, + 'UmUserNotes' => 0x06, + 'UmAttDuration' => 0x07, + 'UmAttOrder' => 0x08, + 'ConversationId' => 0x09, + 'ConversationIndex' => 0x0a, + 'LastVerbExecuted' => 0x0b, + 'LastVerbExecutionTime' => 0x0c, + 'ReceivedAsBcc' => 0x0d, + 'Sender' => 0x0e, + 'CalendarType' => 0x0f, + 'IsLeapMonth' => 0x10, + 'AccountId' => 0x11, + 'FirstDayOfWeek' => 0x12, + 'MeetingMessageType' => 0x13, + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage23.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage23.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage23.php @@ -0,0 +1,32 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage23 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 23; + + protected $_codePageName = 'Notes'; + + protected $_tags = array( + 'Subject' => 0x05, + 'MessageClass' => 0x06, + 'LastModifiedDate' => 0x07, + 'Categories' => 0x08, + 'Category' => 0x09, + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage24.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage24.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage24.php @@ -0,0 +1,48 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage24 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 24; + + protected $_codePageName = 'RightsManagement'; + + protected $_tags = array( + 'RightsManagementSupport' => 0x05, + 'RightsManagementTemplates' => 0x06, + 'RightsManagementTemplate' => 0x07, + 'RightsManagementLicense' => 0x08, + 'ReplyAllowed' => 0x09, + 'EditAllowed' => 0x0a, + 'ReplyAllAllowed' => 0x0b, + 'ForwardAllowed' => 0x0c, + 'ModifyRecipientsAllowed' => 0x0d, + 'ExtractAllowed' => 0x0e, + 'PrintAllowed' => 0x0f, + 'ExportAllowed' => 0x10, + 'ProgrammaticAccessAllowed' => 0x11, + 'RMOwner' => 0x12, + 'ContentExpiryDate' => 0x13, + 'TemplateName' => 0x14, + 'TemplateID' => 0x15, + 'TemplateDescription' => 0x16, + 'ContentOwner' => 0x17, + 'RemoveRightsManagementDistribution' => 0x18 + ); + +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage254.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage254.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage254.php @@ -0,0 +1,31 @@ + + */ + +/** + * class documentation + * + * @link http://msdn.microsoft.com/en-us/live/jj572363.aspx + * @package Wbxml + * @subpackage ActiveSync + */ +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage254 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 254; + + protected $_codePageName = 'WindowsLive'; + + protected $_tags = array( + 'Annotations' => 0x05, + 'Annotation' => 0x06, + 'Name' => 0x07, + 'Value' => 0x08 + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage3.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage3.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage3.php @@ -0,0 +1,49 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage3 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 3; + + protected $_codePageName = 'AirNotify'; + + protected $_tags = array( + 'Notify' => 0x05, + 'Notification' => 0x06, + 'Version' => 0x07, + 'Lifetime' => 0x08, + 'DeviceInfo' => 0x09, + 'Enable' => 0x0a, + 'Folder' => 0x0b, + 'ServerId' => 0x0c, + 'DeviceAddress' => 0x0d, + 'ValidCarrierProfiles' => 0x0e, + 'CarrierProfile' => 0x0f, + 'Status' => 0x10, + 'Responses' => 0x11, + 'Devices' => 0x12, + 'Device' => 0x13, + 'Id' => 0x14, + 'Expiry' => 0x15, + 'NotifyGUID' => 0x16, + 'DeivceFriendlyName' => 0x17 + ); + + // attribute page + #"Version='1.1'" => 0x05, +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage4.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage4.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage4.php @@ -0,0 +1,74 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage4 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 4; + + protected $_codePageName = 'Calendar'; + + protected $_tags = array( + 'Timezone' => 0x05, + 'AllDayEvent' => 0x06, + 'Attendees' => 0x07, + 'Attendee' => 0x08, + 'Email' => 0x09, + 'Name' => 0x0a, + 'Body' => 0x0b, + 'BodyTruncated' => 0x0c, + 'BusyStatus' => 0x0d, + 'Categories' => 0x0e, + 'Category' => 0x0f, + 'Rtf' => 0x10, + 'DtStamp' => 0x11, + 'EndTime' => 0x12, + 'Exception' => 0x13, + 'Exceptions' => 0x14, + 'Deleted' => 0x15, + 'ExceptionStartTime' => 0x16, + 'Location' => 0x17, + 'MeetingStatus' => 0x18, + 'OrganizerEmail' => 0x19, + 'OrganizerName' => 0x1a, + 'Recurrence' => 0x1b, + 'Type' => 0x1c, + 'Until' => 0x1d, + 'Occurrences' => 0x1e, + 'Interval' => 0x1f, + 'DayOfWeek' => 0x20, + 'DayOfMonth' => 0x21, + 'WeekOfMonth' => 0x22, + 'MonthOfYear' => 0x23, + 'Reminder' => 0x24, + 'Sensitivity' => 0x25, + 'Subject' => 0x26, + 'StartTime' => 0x27, + 'UID' => 0x28, + 'AttendeeStatus' => 0x29, + 'AttendeeType' => 0x2a, + 'DisallowNewTimeProposal' => 0x33, + 'ResponseRequested' => 0x34, + 'AppointmentReplyTime' => 0x35, + 'ResponseType' => 0x36, + 'CalendarType' => 0x37, + 'IsLeapMonth' => 0x38, + 'FirstDayOfWeek' => 0x39, + 'OnlineMeetingConfLink' => 0x3a, + 'OnlineMeetingExternalLink' => 0x3b + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage5.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage5.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage5.php @@ -0,0 +1,35 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage5 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 5; + + protected $_codePageName = 'Move'; + + protected $_tags = array( + 'MoveItems' => 0x05, + 'Move' => 0x06, + 'SrcMsgId' => 0x07, + 'SrcFldId' => 0x08, + 'DstFldId' => 0x09, + 'Response' => 0x0a, + 'Status' => 0x0b, + 'DstMsgId' => 0x0c + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage6.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage6.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage6.php @@ -0,0 +1,37 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage6 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 6; + + protected $_codePageName = 'ItemEstimate'; + + protected $_tags = array( + 'GetItemEstimate' => 0x05, + 'Version' => 0x06, + 'Collections' => 0x07, + 'Collection' => 0x08, + 'Class' => 0x09, + 'CollectionId' => 0x0a, + 'DateTime' => 0x0b, + 'Estimate' => 0x0c, + 'Response' => 0x0d, + 'Status' => 0x0e + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage7.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage7.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage7.php @@ -0,0 +1,47 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage7 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 7; + + protected $_codePageName = 'FolderHierarchy'; + + protected $_tags = array( + 'Folders' => 0x05, + 'Folder' => 0x06, + 'DisplayName' => 0x07, + 'ServerId' => 0x08, + 'ParentId' => 0x09, + 'Type' => 0x0a, + 'Response' => 0x0b, + 'Status' => 0x0c, + 'ContentClass' => 0x0d, + 'Changes' => 0x0e, + 'Add' => 0x0f, + 'Delete' => 0x10, + 'Update' => 0x11, + 'SyncKey' => 0x12, + 'FolderCreate' => 0x13, + 'FolderDelete' => 0x14, + 'FolderUpdate' => 0x15, + 'FolderSync' => 0x16, + 'Count' => 0x17, + 'Version' => 0x18 // not used anymore + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage8.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage8.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage8.php @@ -0,0 +1,37 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage8 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 8; + + protected $_codePageName = 'MeetingResponse'; + + protected $_tags = array( + 'CalendarId' => 0x05, + 'CollectionId' => 0x06, + 'MeetingResponse' => 0x07, + 'RequestId' => 0x08, + 'Request' => 0x09, + 'Result' => 0x0a, + 'Status' => 0x0b, + 'UserResponse' => 0x0c, + 'Version' => 0x0d, // not used anymore + 'InstanceId' => 0x0e + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage9.php b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage9.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/ActiveSync/CodePage9.php @@ -0,0 +1,61 @@ + + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage ActiveSync + */ + +class Syncroton_Wbxml_Dtd_ActiveSync_CodePage9 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract +{ + protected $_codePageNumber = 9; + + protected $_codePageName = 'Tasks'; + + protected $_tags = array( + 'Body' => 0x05, + 'BodySize' => 0x06, + 'BodyTruncated' => 0x07, + 'Categories' => 0x08, + 'Category' => 0x09, + 'Complete' => 0x0a, + 'DateCompleted' => 0x0b, + 'DueDate' => 0x0c, + 'UtcDueDate' => 0x0d, + 'Importance' => 0x0e, + 'Recurrence' => 0x0f, + 'Type' => 0x10, + 'Start' => 0x11, + 'Until' => 0x12, + 'Occurrences' => 0x13, + 'Interval' => 0x14, + 'DayOfWeek' => 0x16, + 'DayOfMonth' => 0x15, + 'WeekOfMonth' => 0x17, + 'MonthOfYear' => 0x18, + 'Regenerate' => 0x19, + 'DeadOccur' => 0x1a, + 'ReminderSet' => 0x1b, + 'ReminderTime' => 0x1c, + 'Sensitivity' => 0x1d, + 'StartDate' => 0x1e, + 'UtcStartDate' => 0x1f, + 'Subject' => 0x20, + 'Rtf' => 0x21, + 'OrdinalDate' => 0x22, + 'SubOrdinalDate' => 0x23, + 'CalendarType' => 0x24, + 'IsLeapMonth' => 0x25, + 'FirstDayOfWeek' => 0x26, + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/Exception/CodePageNotFound.php b/src/include/Syncroton/Wbxml/Dtd/Exception/CodePageNotFound.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/Exception/CodePageNotFound.php @@ -0,0 +1,22 @@ + + * @version $Id:CodePageNotFound.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Wbxml + */ + + class Syncroton_Wbxml_Dtd_Exception_CodePageNotFound extends Exception + { + } \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/Factory.php b/src/include/Syncroton/Wbxml/Dtd/Factory.php new file mode 100755 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/Factory.php @@ -0,0 +1,49 @@ + + * @version $Id:Factory.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Wbxml + */ + +class Syncroton_Wbxml_Dtd_Factory +{ + const ACTIVESYNC='AirSync'; + + const SYNCML='SyncML'; + + /** + * factory function to return a selected contacts backend class + * + * @param string $type + * @return Addressbook_Backend_Interface + */ + static public function factory ($_type) + { + switch ($_type) { + case self::ACTIVESYNC: + $instance = new Syncroton_Wbxml_Dtd_ActiveSync(); + break; + + case self::SYNCML: + $instance = new Syncroton_Wbxml_Dtd_Syncml(); + break; + + default: + throw new Syncroton_Wbxml_Exception('unsupported DTD: ' . $_type); + break; + } + return $instance; + } +} diff --git a/src/include/Syncroton/Wbxml/Dtd/Syncml.php b/src/include/Syncroton/Wbxml/Dtd/Syncml.php new file mode 100755 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/Syncml.php @@ -0,0 +1,42 @@ + + * @version $Id:Factory.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Syncml + */ + +class Syncroton_Wbxml_Dtd_Syncml +{ + /** + * factory function to return a selected contacts backend class + * + * @param string $type + * @return Addressbook_Backend_Interface + */ + static public function factory ($_type) + { + switch ($_type) { + case 'syncml:syncml1.1': + case 'syncml:syncml1.2': + case 'syncml:metinf1.1': + case 'syncml:metinf1.2': + case 'syncml:devinf1.1': + case 'syncml:devinf1.2': + throw new Syncroton_Wbxml_Exception('unsupported DTD: ' . $_type); + break; + } + return $instance; + } +} diff --git a/src/include/Syncroton/Wbxml/Dtd/Syncml/Abstract.php b/src/include/Syncroton/Wbxml/Dtd/Syncml/Abstract.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/Syncml/Abstract.php @@ -0,0 +1,103 @@ + + * @version $Id:Abstract.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Syncml + */ + +class Syncroton_Wbxml_Dtd_Syncml_Abstract +{ + protected $_tags; + + protected $_identity; + + protected $_codePages; + + protected $_currentCodePage; + + public function __construct($_initialCodePage = 0x00) + { + $this->switchCodePage($_initialCodePage); + } + + /** + * switch codepage + * + * @param integer $_id id of the codePage + * @return array + */ + public function switchCodePage($_id) + { + if(!isset($this->_codePages[$_id])) { + throw new Syncroton_Wbxml_Dtd_Exception_CodePageNotFound('invalid codePage id: ' . $_id); + } + $this->_currentCodePage = $_id; + $this->_tags = $this->_codePages[$this->_currentCodePage]['tags']; + $this->_identity = array_flip($this->_tags); + + return $this->_codePages[$this->_currentCodePage]; + } + + /** + * get currently active codepage + * + * @return array + */ + public function getCurrentCodePage() + { + return $this->_codePages[$this->_currentCodePage]; + } + + public function getTag($_identity) + { + if(!isset($this->_identity[$_identity])) { + throw new Syncroton_Wbxml_Exception("identity $_identity not found"); + } + + return $this->_identity[$_identity]; + } + + public function getIdentity($_tag) + { + if(!isset($this->_tags[$_tag])) { + var_dump($this->_tags); + throw new Syncroton_Wbxml_Exception("tag $_tag not found"); + } + + return $this->_tags[$_tag]; + } + + /** + * switch codepage by urn + * + * @param string $_urn + * @return array + */ + public function switchCodePageByUrn($_urn) + { + $codePageNumber = NULL; + foreach($this->_codePages as $codePage) { + if($codePage['urn'] == $_urn) { + $codePageNumber = $codePage['codePageNumber']; + } + } + + if($codePageNumber === NULL) { + throw new Syncroton_Wbxml_Dtd_Exception_CodePageNotFound("codePage with URN $_urn not found"); + } + + return $this->switchCodePage($codePageNumber); + } +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/Syncml/DevInfo11.php b/src/include/Syncroton/Wbxml/Dtd/Syncml/DevInfo11.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/Syncml/DevInfo11.php @@ -0,0 +1,71 @@ + + * @version $Id:DevInfo11.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Syncml + */ + +class Syncroton_Wbxml_Dtd_Syncml_DevInfo11 extends Syncroton_Wbxml_Dtd_Syncml_Abstract +{ + protected $_codePages = array( + 0x00 => array( + 'codePageNumber'=> 0x00, + 'dtdname' => 'DevInf', + 'dpi' => '-//SYNCML//DTD DevInf 1.1//EN', + 'url' => 'http://www.syncml.org/docs/devinf_v11_20020215.dtd', + 'urn' => 'syncml:devinf1.1', + 'tags' => array( + "CTCap" => 0x05, + "CTType" => 0x06, + "DataStore" => 0x07, + "DataType" => 0x08, + "DevID" => 0x09, + "DevInf" => 0x0a, + "DevTyp" => 0x0b, + "DisplayName" => 0x0c, + "DSMem" => 0x0d, + "Ext" => 0x0e, + "FwV" => 0x0f, + "HwV" => 0x10, + "Man" => 0x11, + "MaxGUIDSize" => 0x12, + "MaxID" => 0x13, + "MaxMem" => 0x14, + "Mod" => 0x15, + "OEM" => 0x16, + "ParamName" => 0x17, + "PropName" => 0x18, + "Rx" => 0x19, + "Rx-Pref" => 0x1a, + "SharedMem" => 0x1b, + "Size" => 0x1c, + "SourceRef" => 0x1d, + "SwV" => 0x1e, + "SyncCap" => 0x1f, + "SyncType" => 0x20, + "Tx" => 0x21, + "Tx-Pref" => 0x22, + "ValEnum" => 0x23, + "VerCT" => 0x24, + "VerDTD" => 0x25, + "XNam" => 0x26, + "XVal" => 0x27, + "UTC" => 0x28, + "SupportNumberOfChanges"=> 0x29, + "SupportLargeObjs" => 0x2a + ) + ) + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/Syncml/DevInfo12.php b/src/include/Syncroton/Wbxml/Dtd/Syncml/DevInfo12.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/Syncml/DevInfo12.php @@ -0,0 +1,80 @@ + + * @version $Id:DevInfo12.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Syncml + */ + +class Syncroton_Wbxml_Dtd_Syncml_DevInfo12 extends Syncroton_Wbxml_Dtd_Syncml_Abstract +{ + protected $_codePages = array( + 0x00 => array( + 'codePageNumber'=> 0x00, + 'dtdname' => 'DevInf', + 'dpi' => '-//OMA//DTD SYNCML-DEVINF 1.2//EN', + 'url' => 'http://www.openmobilealliance.org/tech/DTD/OMA-SyncML-Device_Information-DTD-1.2.dtd', + 'urn' => 'syncml:devinf1.2', + 'tags' => array( + "CTCap" => 0x05, + "CTType" => 0x06, + "DataStore" => 0x07, + "DataType" => 0x08, + "DevID" => 0x09, + "DevInf" => 0x0a, + "DevTyp" => 0x0b, + "DisplayName" => 0x0c, + "DSMem" => 0x0d, + "Ext" => 0x0e, + "FwV" => 0x0f, + "HwV" => 0x10, + "Man" => 0x11, + "MaxGUIDSize" => 0x12, + "MaxID" => 0x13, + "MaxMem" => 0x14, + "Mod" => 0x15, + "OEM" => 0x16, + "ParamName" => 0x17, + "PropName" => 0x18, + "Rx" => 0x19, + "Rx-Pref" => 0x1a, + "SharedMem" => 0x1b, + "Size" => 0x1c, + "SourceRef" => 0x1d, + "SwV" => 0x1e, + "SyncCap" => 0x1f, + "SyncType" => 0x20, + "Tx" => 0x21, + "Tx-Pref" => 0x22, + "ValEnum" => 0x23, + "VerCT" => 0x24, + "VerDTD" => 0x25, + "XNam" => 0x26, + "XVal" => 0x27, + "UTC" => 0x28, + "SupportNumberOfChanges"=> 0x29, + "SupportLargeObjs" => 0x2a, + "Property" => 0x2b, + "PropParam" => 0x2c, + "MaxOccur" => 0x2d, + "NoTruncate" => 0x2e, + "Filter-Rx" => 0x30, + "FilterCap" => 0x31, + "FilterKeyword" => 0x32, + "FieldLevel" => 0x33, + "SupportHierarchicalSync"=> 0x34 + ) + ) + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/Syncml/Syncml11.php b/src/include/Syncroton/Wbxml/Dtd/Syncml/Syncml11.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/Syncml/Syncml11.php @@ -0,0 +1,107 @@ + + * @version $Id:Syncml11.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Syncml + */ + +class Syncroton_Wbxml_Dtd_Syncml_Syncml11 extends Syncroton_Wbxml_Dtd_Syncml_Abstract +{ + protected $_codePages = array( + 0x00 => array( + 'codePageNumber'=> 0x00, + 'dtdname' => 'SyncML', + 'dpi' => '-//SYNCML//DTD SyncML 1.1//EN', + 'url' => "http://www.syncml.org/docs/syncml_represent_v11_20020213.dtd", + 'urn' => 'syncml:syncml1.1', + 'tags' => array( + 'Add' => 0x05, + 'Alert' => 0x06, + 'Archive' => 0x07, + 'Atomic' => 0x08, + 'Chal' => 0x09, + 'Cmd' => 0x0a, + 'CmdID' => 0x0b, + 'CmdRef' => 0x0c, + 'Copy' => 0x0d, + 'Cred' => 0x0e, + 'Data' => 0x0f, + 'Delete' => 0x10, + 'Exec' => 0x11, + 'Final' => 0x12, + 'Get' => 0x13, + 'Item' => 0x14, + 'Lang' => 0x15, + 'LocName' => 0x16, + 'LocURI' => 0x17, + 'Map' => 0x18, + 'MapItem' => 0x19, + 'Meta' => 0x1a, + 'MsgID' => 0x1b, + 'MsgRef' => 0x1c, + 'NoResp' => 0x1d, + 'NoResults' => 0x1e, + 'Put' => 0x1f, + 'Replace' => 0x20, + 'RespURI' => 0x21, + 'Results' => 0x22, + 'Search' => 0x23, + 'Sequence' => 0x24, + 'SessionID' => 0x25, + 'SftDel' => 0x26, + 'Source' => 0x27, + 'SourceRef' => 0x28, + 'Status' => 0x29, + 'Sync' => 0x2a, + 'SyncBody' => 0x2b, + 'SyncHdr' => 0x2c, + 'SyncML' => 0x2d, + 'Target' => 0x2e, + 'TargetRef' => 0x2f, + 'Reserved for future use.' => 0x30, + 'VerDTD' => 0x31, + 'VerProto' => 0x32, + 'NumberOfChanges' => 0x33, + 'MoreData' => 0x34 + ) + ), + 0x01 => array( + 'codePageNumber'=> 0x01, + 'dtdname' => 'MetInf', + 'dpi' => '-//SYNCML//DTD MetInf 1.1//EN', + 'url' => 'http://www.syncml.org/docs/syncml_metinf_v11_20020215.dtd ', + 'urn' => 'syncml:metinf1.1', + 'tags' => array( + 'Anchor' => 0x05, + 'EMI' => 0x06, + 'Format' => 0x07, + 'FreeID' => 0x08, + 'FreeMem' => 0x09, + 'Last' => 0x0a, + 'Mark' => 0x0b, + 'MaxMsgSize' => 0x0c, + 'Mem' => 0x0d, + 'MetInf' => 0x0e, + 'Next' => 0x0f, + 'NextNonce' => 0x10, + 'SharedMem' => 0x11, + 'Size' => 0x12, + 'Type' => 0x13, + 'Version' => 0x14, + 'MaxObjSize' => 0x15 + ) + ) + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Dtd/Syncml/Syncml12.php b/src/include/Syncroton/Wbxml/Dtd/Syncml/Syncml12.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Dtd/Syncml/Syncml12.php @@ -0,0 +1,122 @@ + + * @version $Id:Syncml12.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Syncml + */ + +class Syncroton_Wbxml_Dtd_Syncml_Syncml12 extends Syncroton_Wbxml_Dtd_Syncml_Abstract +{ + + /** + * section 8.2 + * + * @var array + */ + protected $_codePages = array( + 0x00 => array( + 'codePageNumber'=> 0x00, + 'dtdname' => 'SyncML', + 'dpi' => '-//SYNCML//DTD SyncML 1.2//EN', + 'url' => 'http://www.openmobilealliance.org/tech/DTD/OMA-TS-SyncML_RepPro_DTD-V1_2.dtd', + 'urn' => 'SYNCML:SYNCML1.2', + 'tags' => array( + 'Add' => 0x05, + 'Alert' => 0x06, + 'Archive' => 0x07, + 'Atomic' => 0x08, + 'Chal' => 0x09, + 'Cmd' => 0x0a, + 'CmdID' => 0x0b, + 'CmdRef' => 0x0c, + 'Copy' => 0x0d, + 'Cred' => 0x0e, + 'Data' => 0x0f, + 'Delete' => 0x10, + 'Exec' => 0x11, + 'Final' => 0x12, + 'Get' => 0x13, + 'Item' => 0x14, + 'Lang' => 0x15, + 'LocName' => 0x16, + 'LocURI' => 0x17, + 'Map' => 0x18, + 'MapItem' => 0x19, + 'Meta' => 0x1a, + 'MsgID' => 0x1b, + 'MsgRef' => 0x1c, + 'NoResp' => 0x1d, + 'NoResults' => 0x1e, + 'Put' => 0x1f, + 'Replace' => 0x20, + 'RespURI' => 0x21, + 'Results' => 0x22, + 'Search' => 0x23, + 'Sequence' => 0x24, + 'SessionID' => 0x25, + 'SftDel' => 0x26, + 'Source' => 0x27, + 'SourceRef' => 0x28, + 'Status' => 0x29, + 'Sync' => 0x2a, + 'SyncBody' => 0x2b, + 'SyncHdr' => 0x2c, + 'SyncML' => 0x2d, + 'Target' => 0x2e, + 'TargetRef' => 0x2f, + 'Reserved for future use.' => 0x30, + 'VerDTD' => 0x31, + 'VerProto' => 0x32, + 'NumberOfChanges' => 0x33, + 'MoreData' => 0x34, + 'Field' => 0x35, + 'Filter' => 0x36, + 'Record' => 0x37, + 'FilterType' => 0x38, + 'SourceParent' => 0x39, + 'TargetParent' => 0x3a, + 'Move' => 0x3b, + 'Correlator' => 0x3c + ) + ), + 0x01 => array( + 'codePageNumber'=> 0x01, + 'dtdname' => 'MetInf', + 'dpi' => '-//OMA//DTD SYNCML-METINF 1.2//EN', + 'url' => 'http://www.openmobilealliance.org/tech/DTD/OMA-TS-SyncML_MetaInfo_DTD-V1_2.dtd', + 'urn' => 'syncml:metinf1.2', + 'tags' => array( + 'Anchor' => 0x05, + 'EMI' => 0x06, + 'Format' => 0x07, + 'FreeID' => 0x08, + 'FreeMem' => 0x09, + 'Last' => 0x0a, + 'Mark' => 0x0b, + 'MaxMsgSize' => 0x0c, + 'Mem' => 0x0d, + 'MetInf' => 0x0e, + 'Next' => 0x0f, + 'NextNonce' => 0x10, + 'SharedMem' => 0x11, + 'Size' => 0x12, + 'Type' => 0x13, + 'Version' => 0x14, + 'MaxObjSize' => 0x15, + 'FieldLevel' => 0x16 + ) + ) + ); +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Encoder.php b/src/include/Syncroton/Wbxml/Encoder.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Encoder.php @@ -0,0 +1,372 @@ + + * @version $Id:Encoder.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class to convert XML to WBXML + * + * @package Wbxml + * @subpackage Wbxml + */ + +class Syncroton_Wbxml_Encoder extends Syncroton_Wbxml_Abstract +{ + /** + * stack of dtd objects + * + * @var array + */ + protected $_dtdStack = array(); + + /** + * stack of stream resources + * + * @var array + */ + protected $_streamStack = array(); + + /** + * stack of levels when to pop data from the other stacks + * + * @var array + */ + protected $_popStack = array(); + + /** + * count level of tags + * + * @var string + */ + protected $_level = 0; + + /** + * when to take data next time from the different stacks + * + * @var unknown_type + */ + protected $_nextStackPop = NULL; + + /** + * collect data trough different calls to _handleCharacters + * + * @var string + */ + protected $_currentTagData = NULL; + + /** + * the current tag as read by the parser + * + * @var string + */ + protected $_currentTag = NULL; + + /** + * the constructor + * + * @param resource $_stream + * @param string $_charSet + * @param integer $_version + */ + public function __construct($_stream, $_charSet = 'UTF-8', $_version = 2) + { + $this->_stream = $_stream; + $this->_charSet = $_charSet; + $this->_version = $_version; + } + + /** + * initialize internal variables and write wbxml header to stream + * + * @param string $_urn + * @todo check if dpi > 0, instead checking the urn + */ + protected function _initialize($_dom) + { + $this->_dtd = Syncroton_Wbxml_Dtd_Factory::factory($_dom->doctype->name); + $this->_codePage = $this->_dtd->getCurrentCodePage(); + + // the WBXML version + $this->_writeByte($this->_version); + + if($this->_codePage->getDPI() === NULL) { + // the document public identifier + $this->_writeMultibyteUInt(1); + } else { + // the document public identifier + // defined in string table + $this->_writeMultibyteUInt(0); + // the offset of the DPI in the string table + $this->_writeByte(0); + } + + // write the charSet + $this->_writeCharSet($this->_charSet); + + if($this->_codePage->getDPI() === NULL) { + // the length of the string table + $this->_writeMultibyteUInt(0); + } else { + // the length of the string table + $this->_writeMultibyteUInt(strlen($this->_codePage->getDPI())); + // the dpi + $this->_writeString($this->_codePage->getDPI()); + } + } + + /** + * write charset to stream + * + * @param string $_charSet + * @todo add charset lookup table. currently only utf-8 is supported + */ + protected function _writeCharSet($_charSet) + { + switch(strtoupper($_charSet)) { + case 'UTF-8': + $this->_writeMultibyteUInt(106); + break; + + default: + throw new Syncroton_Wbxml_Exception('unsuported charSet ' . strtoupper($_charSet)); + break; + } + + } + + /** + * start encoding of xml to wbxml + * + * @param string $_xml the xml string + * @return resource stream + */ + public function encode(DOMDocument $_dom) + { + $_dom->formatOutput = false; + + $tempStream = tmpfile(); + + $meta_data = stream_get_meta_data($tempStream); + $filename = $meta_data["uri"]; + $_dom->save($filename); + rewind($tempStream); + + $this->_initialize($_dom); + + $parser = xml_parser_create_ns($this->_charSet, ';'); + xml_set_object($parser, $this); + xml_set_element_handler($parser, '_handleStartTag', '_handleEndTag'); + xml_set_character_data_handler($parser, '_handleCharacters'); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + + while (!feof($tempStream)) { + if (!xml_parse($parser, fread($tempStream, 1048576), feof($tempStream))) { + // uncomment to write xml document to file + #rewind($tempStream); + #$xmlStream = fopen(tempnam(sys_get_temp_dir(), "xmlerrors"), 'r+'); + #stream_copy_to_stream($tempStream, $xmlStream); + #fclose($xmlStream); + + throw new Syncroton_Wbxml_Exception(sprintf('XML error: %s at line %d', + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser) + )); + } + } + + fclose($tempStream); + xml_parser_free($parser); + } + + /** + * get's called by xml parser when tag starts + * + * @param resource $_parser + * @param string $_tag current tag prefixed with namespace + * @param array $_attributes list of tag attributes + */ + protected function _handleStartTag($_parser, $_tag, $_attributes) + { + $this->_level++; + $this->_currentTagData = null; + + // write data for previous tag happens whith + if($this->_currentTag !== NULL) { + $this->_writeTag($this->_currentTag, $this->_attributes, true); + } + + list($nameSpace, $this->_currentTag) = explode(';', $_tag); + + if($this->_codePage->getNameSpace() != $nameSpace) { + $this->_switchCodePage($nameSpace); + } + + $this->_attributes = $_attributes; + + } + + /** + * strip uri: from nameSpace + * + * @param unknown_type $_nameSpace + * @return unknown + */ + protected function _stripNameSpace($_nameSpace) + { + return substr($_nameSpace, 4); + } + + /** + * get's called by xml parser when tag ends + * + * @param resource $_parser + * @param string $_tag current tag prefixed with namespace + */ + protected function _handleEndTag($_parser, $_tag) + { + #echo "$_tag Level: $this->_level == $this->_nextStackPop \n"; + + if($this->_nextStackPop !== NULL && $this->_nextStackPop == $this->_level) { + #echo "TAG: $_tag\n"; + $this->_writeByte(Syncroton_Wbxml_Abstract::END); + + $subStream = $this->_stream; + $subStreamLength = ftell($subStream); + + $this->_dtd = array_pop($this->_dtdStack); + $this->_stream = array_pop($this->_streamStack); + $this->_nextStackPop = array_pop($this->_popStack); + $this->_codePage = $this->_dtd->getCurrentCodePage(); + + rewind($subStream); + #while (!feof($subStream)) {$buffer = fgets($subStream, 4096);echo $buffer;} + $this->_writeByte(Syncroton_Wbxml_Abstract::OPAQUE); + $this->_writeMultibyteUInt($subStreamLength); + + $writenBytes = stream_copy_to_stream($subStream, $this->_stream); + if($writenBytes !== $subStreamLength) { + //echo "$writenBytes !== $subStreamLength\n"; + throw new Syncroton_Wbxml_Exception('blow'); + } + fclose($subStream); + #echo "$this->_nextStackPop \n"; exit; + } else { + if ($this->_currentTag !== NULL && $this->_currentTagData !== NULL) { + $this->_writeTag($this->_currentTag, $this->_attributes, true, $this->_currentTagData); + $this->_writeByte(Syncroton_Wbxml_Abstract::END); + } elseif ($this->_currentTag !== NULL && $this->_currentTagData === NULL) { + // for example tag with no data, jumps directly from _handleStartTag to _handleEndTag + $this->_writeTag($this->_currentTag, $this->_attributes); + // no end tag required, tag has no content + } else { + $this->_writeByte(Syncroton_Wbxml_Abstract::END); + } + } + + #list($urn, $tag) = explode(';', $_tag); echo " ($this->_level)\n"; + + // reset $this->_currentTag, as tag got writen to stream already + $this->_currentTag = NULL; + + $this->_level--; + } + + /** + * collects data(value) of tag + * can be called multiple lines if the value contains linebreaks + * + * @param resource $_parser the xml parser + * @param string $_data the data(value) of the tag + */ + protected function _handleCharacters($_parser, $_data) + { + $this->_currentTagData .= $_data; + } + + /** + * writes tag with data to stream + * + * @param string $_tag + * @param array $_attributes + * @param bool $_hasContent + * @param string $_data + */ + protected function _writeTag($_tag, $_attributes=NULL, $_hasContent=false, $_data=NULL) + { + if($_hasContent == false && $_data !== NULL) { + throw new Syncroton_Wbxml_Exception('$_hasContent can not be false, when $_data !== NULL'); + } + + // handle the tag + $identity = $this->_codePage->getIdentity($_tag); + + if (is_array($_attributes) && isset($_attributes['uri:Syncroton;encoding'])) { + $encoding = 'opaque'; + unset($_attributes['uri:Syncroton;encoding']); + } else { + $encoding = 'termstring'; + } + + if(!empty($_attributes)) { + $identity |= 0x80; + } + + if($_hasContent == true) { + $identity |= 0x40; + } + + $this->_writeByte($identity); + + // handle the data + if($_data !== NULL) { + if ($encoding == 'opaque') { + $this->_writeOpaqueString(base64_decode($_data)); + } else { + $this->_writeTerminatedString($_data); + } + } + + $this->_currentTagData = NULL; + } + + /** + * switch code page + * + * @param string $_urn + */ + protected function _switchCodePage($_nameSpace) + { + try { + $codePageName = $this->_stripNameSpace($_nameSpace); + if(!defined('Syncroton_Wbxml_Dtd_ActiveSync::CODEPAGE_'. strtoupper($codePageName))) { + throw new Syncroton_Wbxml_Exception('codepage ' . $codePageName . ' not found' . $_nameSpace); + } + // switch to another codepage + // no need to write the wbxml header again + $codePageId = constant('Syncroton_Wbxml_Dtd_ActiveSync::CODEPAGE_'. strtoupper($codePageName)); + $this->_codePage = $this->_dtd->switchCodePage($codePageId); + + $this->_writeByte(Syncroton_Wbxml_Abstract::SWITCH_PAGE); + $this->_writeByte($codePageId); + } catch (Syncroton_Wbxml_Dtd_Exception_CodePageNotFound $e) { + // switch to another dtd + // need to write the wbxml header again + // put old dtd and stream on stack + $this->_dtdStack[] = $this->_dtd; + $this->_streamStack[] = $this->_stream; + $this->_popStack[] = $this->_nextStackPop; + $this->_nextStackPop = $this->_level; + + $this->_stream = fopen("php://temp", 'r+'); + + $this->_initialize($_urn); + } + } +} diff --git a/src/include/Syncroton/Wbxml/Exception.php b/src/include/Syncroton/Wbxml/Exception.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Exception.php @@ -0,0 +1,23 @@ + + * @version $Id:Factory.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Wbxml + */ + +class Syncroton_Wbxml_Exception extends Exception +{ + protected $message = 'wbxml exception'; +} \ No newline at end of file diff --git a/src/include/Syncroton/Wbxml/Exception/UnexpectedEndOfFile.php b/src/include/Syncroton/Wbxml/Exception/UnexpectedEndOfFile.php new file mode 100644 --- /dev/null +++ b/src/include/Syncroton/Wbxml/Exception/UnexpectedEndOfFile.php @@ -0,0 +1,23 @@ + + * @version $Id:Factory.php 4968 2008-10-17 09:09:33Z l.kneschke@metaways.de $ + */ + +/** + * class documentation + * + * @package Wbxml + * @subpackage Wbxml + */ + +class Syncroton_Wbxml_Exception_UnexpectedEndOfFile extends Syncroton_Wbxml_Exception +{ + protected $message = 'unexpcted end of file detected'; +} \ No newline at end of file