dom/wappush/src/gonk/WbxmlPduHelper.jsm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 "use strict";
michael@0 6
michael@0 7 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
michael@0 8
michael@0 9 let WSP = {};
michael@0 10 Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
michael@0 11
michael@0 12 /**
michael@0 13 * Token flags
michael@0 14 *
michael@0 15 * @see WAP-192-WBXML-20010725-A, clause 5.8.2
michael@0 16 */
michael@0 17 const TAG_TOKEN_ATTR_MASK = 0x80;
michael@0 18 const TAG_TOKEN_CONTENT_MASK = 0x40;
michael@0 19 const TAG_TOKEN_VALUE_MASK = 0x3F;
michael@0 20
michael@0 21 /**
michael@0 22 * Global tokens
michael@0 23 *
michael@0 24 * @see WAP-192-WBXML-20010725-A, clause 7.1
michael@0 25 */
michael@0 26 const CODE_PAGE_SWITCH_TOKEN = 0x00;
michael@0 27 const TAG_END_TOKEN = 0x01;
michael@0 28 const INLINE_STRING_TOKEN = 0x03;
michael@0 29 const STRING_TABLE_TOKEN = 0x83;
michael@0 30 const OPAQUE_TOKEN = 0xC3;
michael@0 31
michael@0 32 // Set to true to enable debug message on all WBXML decoders.
michael@0 33 this.DEBUG_ALL = false;
michael@0 34
michael@0 35 // Enable debug message for WBXML decoder core.
michael@0 36 this.DEBUG = DEBUG_ALL | false;
michael@0 37
michael@0 38 /**
michael@0 39 * Handle WBXML code page switch.
michael@0 40 *
michael@0 41 * @param data
michael@0 42 * A wrapped object containing raw PDU data.
michael@0 43 * @param decodeInfo
michael@0 44 * Internal information for decode process.
michael@0 45 *
michael@0 46 * @see WAP-192-WBXML-20010725-A, clause 5.8.4.7.2 and 5.8.1
michael@0 47 */
michael@0 48 this.WbxmlCodePageSwitch = {
michael@0 49 decode: function decode_wbxml_code_page_switch(data, decodeInfo) {
michael@0 50 let codePage = WSP.Octet.decode(data);
michael@0 51
michael@0 52 if (decodeInfo.currentState === "tag") {
michael@0 53 decodeInfo.currentTokenList.tag = decodeInfo.tokenList.tag[codePage];
michael@0 54
michael@0 55 if (!decodeInfo.currentTokenList.tag) {
michael@0 56 throw new Error("Invalid tag code page: " + codePage + ".");
michael@0 57 }
michael@0 58
michael@0 59 return "";
michael@0 60 }
michael@0 61
michael@0 62 if (decodeInfo.currentState === "attr") {
michael@0 63 decodeInfo.currentTokenList.attr = decodeInfo.tokenList.attr[codePage];
michael@0 64 decodeInfo.currentTokenList.value = decodeInfo.tokenList.value[codePage];
michael@0 65
michael@0 66 if (!decodeInfo.currentTokenList.attr ||
michael@0 67 !decodeInfo.currentTokenList.value) {
michael@0 68 throw new Error("Invalid attr code page: " + codePage + ".");
michael@0 69 }
michael@0 70
michael@0 71 return "";
michael@0 72 }
michael@0 73
michael@0 74 throw new Error("Invalid decoder state: " + decodeInfo.currentState + ".");
michael@0 75 },
michael@0 76 };
michael@0 77
michael@0 78 /**
michael@0 79 * Parse end WBXML encoded message.
michael@0 80 *
michael@0 81 * @param data
michael@0 82 * A wrapped object containing raw PDU data.
michael@0 83 * @param decodeInfo
michael@0 84 * Internal information for decode process.
michael@0 85 *
michael@0 86 * @see WAP-192-WBXML-20010725-A, clause 5.8.4.7.1
michael@0 87 *
michael@0 88 */
michael@0 89 this.WbxmlEnd = {
michael@0 90 decode: function decode_wbxml_end(data, decodeInfo) {
michael@0 91 let tagInfo = decodeInfo.tagStack.pop();
michael@0 92 return "</" + tagInfo.name + ">";
michael@0 93 },
michael@0 94 };
michael@0 95
michael@0 96 /**
michael@0 97 * Escape XML reserved characters &, <, >, " and ' which may appear in the
michael@0 98 * WBXML-encoded strings in their original form.
michael@0 99 *
michael@0 100 * @param str
michael@0 101 * A string with potentially unescaped characters
michael@0 102 *
michael@0 103 * @return A string with the &, <, >, " and ' characters turned into XML
michael@0 104 * character entitites
michael@0 105 *
michael@0 106 * @see WAP-192-WBXML-20010725-A, clause 6.1
michael@0 107 */
michael@0 108 this.escapeReservedCharacters = function escape_reserved_characters(str) {
michael@0 109 let dst = "";
michael@0 110
michael@0 111 for (var i = 0; i < str.length; i++) {
michael@0 112 switch (str[i]) {
michael@0 113 case '&' : dst += "&amp;" ; break;
michael@0 114 case '<' : dst += "&lt;" ; break;
michael@0 115 case '>' : dst += "&gt;" ; break;
michael@0 116 case '"' : dst += "&quot;"; break;
michael@0 117 case '\'': dst += "&apos;"; break;
michael@0 118 default : dst += str[i];
michael@0 119 }
michael@0 120 }
michael@0 121
michael@0 122 return dst;
michael@0 123 }
michael@0 124
michael@0 125 /**
michael@0 126 * Handle string table in WBXML message.
michael@0 127 *
michael@0 128 * @see WAP-192-WBXML-20010725-A, clause 5.7
michael@0 129 */
michael@0 130 this.readStringTable = function decode_wbxml_read_string_table(start, stringTable, charset) {
michael@0 131 let end = start;
michael@0 132
michael@0 133 // Find end of string
michael@0 134 let stringTableLength = stringTable.length;
michael@0 135 while (end < stringTableLength) {
michael@0 136 if (stringTable[end] === 0) {
michael@0 137 break;
michael@0 138 }
michael@0 139 end++;
michael@0 140 }
michael@0 141
michael@0 142 // Read string table
michael@0 143 return WSP.PduHelper.decodeStringContent(stringTable.subarray(start, end),
michael@0 144 charset);
michael@0 145 };
michael@0 146
michael@0 147 this.WbxmlStringTable = {
michael@0 148 decode: function decode_wbxml_string_table(data, decodeInfo) {
michael@0 149 let start = WSP.Octet.decode(data);
michael@0 150 let str = readStringTable(start, decodeInfo.stringTable, decodeInfo.charset);
michael@0 151
michael@0 152 return escapeReservedCharacters(str);
michael@0 153 }
michael@0 154 };
michael@0 155
michael@0 156 /**
michael@0 157 * Parse inline string in WBXML encoded message.
michael@0 158 *
michael@0 159 * @param data
michael@0 160 * A wrapped object containing raw PDU data.
michael@0 161 * @param decodeInfo
michael@0 162 * Internal information for decode process.
michael@0 163 *
michael@0 164 * @see WAP-192-WBXML-20010725-A, clause 5.8.4.1
michael@0 165 *
michael@0 166 */
michael@0 167 this.WbxmlInlineString = {
michael@0 168 decode: function decode_wbxml_inline_string(data, decodeInfo) {
michael@0 169 let charCode = WSP.Octet.decode(data);
michael@0 170 let stringData = [];
michael@0 171 while (charCode) {
michael@0 172 stringData.push(charCode);
michael@0 173 charCode = WSP.Octet.decode(data);
michael@0 174 }
michael@0 175
michael@0 176 let str = WSP.PduHelper.decodeStringContent(stringData, decodeInfo.charset);
michael@0 177
michael@0 178 return escapeReservedCharacters(str);
michael@0 179 },
michael@0 180 };
michael@0 181
michael@0 182 /**
michael@0 183 * Parse inline Opaque data in WBXML encoded message.
michael@0 184 *
michael@0 185 * @param data
michael@0 186 * A wrapped object containing raw PDU data.
michael@0 187 * @param decodeInfo
michael@0 188 * Internal information for decode process.
michael@0 189 *
michael@0 190 * @see WAP-192-WBXML-20010725-A, clause 5.8.4.6
michael@0 191 *
michael@0 192 */
michael@0 193 this.WbxmlOpaque = {
michael@0 194 decode: function decode_wbxml_inline_opaque(data) {
michael@0 195 // Inline OPAQUE must be decoded based on application definition,
michael@0 196 // so it's illegal to run into OPAQUE type in general decoder.
michael@0 197 throw new Error("OPQAUE decoder is not defined.");
michael@0 198 },
michael@0 199 };
michael@0 200
michael@0 201 this.PduHelper = {
michael@0 202
michael@0 203 /**
michael@0 204 * Parse WBXML encoded message into plain text.
michael@0 205 *
michael@0 206 * @param data
michael@0 207 * A wrapped object containing raw PDU data.
michael@0 208 * @param decodeInfo
michael@0 209 * Information for decoding, now requires charset and string table.
michael@0 210 * @param appToken
michael@0 211 * Application-specific token difinition.
michael@0 212 *
michael@0 213 * @return Decoded WBXML message string.
michael@0 214 */
michael@0 215 parseWbxml: function parseWbxml_wbxml(data, decodeInfo, appToken) {
michael@0 216
michael@0 217 // Parse token definition to my structure.
michael@0 218 decodeInfo.tokenList = {
michael@0 219 tag: appToken.tagTokenList,
michael@0 220 attr: appToken.attrTokenList,
michael@0 221 value: appToken.valueTokenList
michael@0 222 };
michael@0 223 decodeInfo.tagStack = []; // tag decode stack
michael@0 224 decodeInfo.currentTokenList = {
michael@0 225 tag: decodeInfo.tokenList.tag[0],
michael@0 226 attr: decodeInfo.tokenList.attr[0],
michael@0 227 value: decodeInfo.tokenList.value[0]
michael@0 228 };
michael@0 229 decodeInfo.currentState = "tag"; // Current decoding state, "tag" or "attr"
michael@0 230 // Used to read corresponding code page
michael@0 231 // initial state : "tag"
michael@0 232
michael@0 233 // Merge global tag tokens into single list, so we don't have
michael@0 234 // to search two lists every time.
michael@0 235 let globalTagTokenList = Object.create(WBXML_GLOBAL_TOKENS);
michael@0 236 if (appToken.globalTokenOverride) {
michael@0 237 let globalTokenOverrideList = appToken.globalTokenOverride;
michael@0 238 for (let token in globalTokenOverrideList) {
michael@0 239 globalTagTokenList[token] = globalTokenOverrideList[token];
michael@0 240 }
michael@0 241 }
michael@0 242
michael@0 243 let content = "";
michael@0 244 while (data.offset < data.array.length) {
michael@0 245 // Decode content, might be a new tag token, an end of tag token, or an
michael@0 246 // inline string.
michael@0 247
michael@0 248 // Switch to tag domain
michael@0 249 decodeInfo.currentState = "tag";
michael@0 250
michael@0 251 let tagToken = WSP.Octet.decode(data);
michael@0 252 let tagTokenValue = tagToken & TAG_TOKEN_VALUE_MASK;
michael@0 253
michael@0 254 // Try global tag first, tagToken of string table is 0x83, and will be 0x03
michael@0 255 // in tagTokenValue, which is collision with inline string.
michael@0 256 // So tagToken need to be searched before tagTokenValue.
michael@0 257 let tagInfo = globalTagTokenList[tagToken] ||
michael@0 258 globalTagTokenList[tagTokenValue];
michael@0 259 if (tagInfo) {
michael@0 260 content += tagInfo.coder.decode(data, decodeInfo);
michael@0 261 continue;
michael@0 262 }
michael@0 263
michael@0 264 // Check if application tag token is valid
michael@0 265 tagInfo = decodeInfo.currentTokenList.tag[tagTokenValue];
michael@0 266 if (!tagInfo) {
michael@0 267 throw new Error("Unsupported WBXML token: " + tagTokenValue + ".");
michael@0 268 }
michael@0 269
michael@0 270 content += "<" + tagInfo.name;
michael@0 271
michael@0 272 if (tagToken & TAG_TOKEN_ATTR_MASK) {
michael@0 273 // Decode attributes, might be a new attribute token, a value token,
michael@0 274 // or an inline string
michael@0 275
michael@0 276 // Switch to attr/value domain
michael@0 277 decodeInfo.currentState = "attr";
michael@0 278
michael@0 279 let attrSeperator = "";
michael@0 280 while (data.offset < data.array.length) {
michael@0 281 let attrToken = WSP.Octet.decode(data);
michael@0 282 if (attrToken === TAG_END_TOKEN) {
michael@0 283 break;
michael@0 284 }
michael@0 285
michael@0 286 let attrInfo = globalTagTokenList[attrToken];
michael@0 287 if (attrInfo) {
michael@0 288 content += attrInfo.coder.decode(data, decodeInfo);
michael@0 289 continue;
michael@0 290 }
michael@0 291
michael@0 292 // Check if attribute token is valid
michael@0 293 attrInfo = decodeInfo.currentTokenList.attr[attrToken];
michael@0 294 if (attrInfo) {
michael@0 295 content += attrSeperator + " " + attrInfo.name + "=\"" + attrInfo.value;
michael@0 296 attrSeperator = "\"";
michael@0 297 continue;
michael@0 298 }
michael@0 299
michael@0 300 attrInfo = decodeInfo.currentTokenList.value[attrToken];
michael@0 301 if (attrInfo) {
michael@0 302 content += attrInfo.value;
michael@0 303 continue;
michael@0 304 }
michael@0 305
michael@0 306 throw new Error("Unsupported WBXML token: " + attrToken + ".");
michael@0 307 }
michael@0 308
michael@0 309 content += attrSeperator;
michael@0 310 }
michael@0 311
michael@0 312 if (tagToken & TAG_TOKEN_CONTENT_MASK) {
michael@0 313 content += ">";
michael@0 314 decodeInfo.tagStack.push(tagInfo);
michael@0 315 continue;
michael@0 316 }
michael@0 317
michael@0 318 content += "/>";
michael@0 319 }
michael@0 320
michael@0 321 return content;
michael@0 322 },
michael@0 323
michael@0 324 /**
michael@0 325 * @param data
michael@0 326 * A wrapped object containing raw PDU data.
michael@0 327 * @param appToken
michael@0 328 * contains application-specific token info, including
michael@0 329 * {
michael@0 330 * publicId : Public identifier of application.
michael@0 331 * tagToken : Ojbect defines application tag tokens.
michael@0 332 * In form of
michael@0 333 * Object[TAG_NAME] = Object[TOKEN_NUMBER] =
michael@0 334 * {
michael@0 335 * name: "TOKEN_NAME",
michael@0 336 * number: TOKEN_NUMBER
michael@0 337 * }
michael@0 338 * attrToken : Object defines application attribute tokens.
michael@0 339 * Object[ATTR_NAME] = Object[TOKEN_NUMBER] =
michael@0 340 * {
michael@0 341 * name: "ATTR_NAME",
michael@0 342 * value: "ATTR_VALUE",
michael@0 343 * number: TOKEN_NUMBER
michael@0 344 * }
michael@0 345 * For attribute value tokens, assign name as ""
michael@0 346 * globalTokenOverride : Object overrides decoding behavior of global tokens.
michael@0 347 * In form of
michael@0 348 * Object[GLOBAL_TOKEN_NUMBER] =
michael@0 349 * {
michael@0 350 * decode: function(data),
michael@0 351 * encode: function(data)
michael@0 352 * }
michael@0 353 * decode() returns decoded text, encode() returns
michael@0 354 * encoded raw data.
michael@0 355 * }
michael@0 356 *
michael@0 357 * @return A WBXML message object or null in case of errors found.
michael@0 358 */
michael@0 359 parse: function parse_wbxml(data, appToken) {
michael@0 360 let msg = {};
michael@0 361
michael@0 362 /**
michael@0 363 * Read WBXML header.
michael@0 364 *
michael@0 365 * @see WAP-192-WBXML-20010725-A, Clause 5.3
michael@0 366 */
michael@0 367 let headerRaw = {};
michael@0 368 headerRaw.version = WSP.Octet.decode(data);
michael@0 369 headerRaw.publicId = WSP.UintVar.decode(data);
michael@0 370 if (headerRaw.publicId === 0) {
michael@0 371 headerRaw.publicIdStr = WSP.UintVar.decode(data);
michael@0 372 }
michael@0 373 headerRaw.charset = WSP.UintVar.decode(data);
michael@0 374
michael@0 375 let stringTableLen = WSP.UintVar.decode(data);
michael@0 376 msg.stringTable =
michael@0 377 WSP.Octet.decodeMultiple(data, data.offset + stringTableLen);
michael@0 378
michael@0 379 // Transform raw header into user-friendly form
michael@0 380 let entry = WSP.WSP_WELL_KNOWN_CHARSETS[headerRaw.charset];
michael@0 381 if (!entry) {
michael@0 382 throw new Error("Charset is not supported.");
michael@0 383 }
michael@0 384 msg.charset = entry.name;
michael@0 385
michael@0 386 if (headerRaw.publicId !== 0) {
michael@0 387 msg.publicId = WBXML_PUBLIC_ID[headerRaw.publicId];
michael@0 388 } else {
michael@0 389 msg.publicId = readStringTable(headerRaw.publicIdStr, msg.stringTable,
michael@0 390 WSP.WSP_WELL_KNOWN_CHARSETS[msg.charset].converter);
michael@0 391 }
michael@0 392 if (msg.publicId != appToken.publicId) {
michael@0 393 throw new Error("Public ID does not match.");
michael@0 394 }
michael@0 395
michael@0 396 msg.version = ((headerRaw.version >> 4) + 1) + "." + (headerRaw.version & 0x0F);
michael@0 397
michael@0 398 let decodeInfo = {
michael@0 399 charset: WSP.WSP_WELL_KNOWN_CHARSETS[msg.charset].converter, // document character set
michael@0 400 stringTable: msg.stringTable // document string table
michael@0 401 };
michael@0 402 msg.content = this.parseWbxml(data, decodeInfo, appToken);
michael@0 403
michael@0 404 return msg;
michael@0 405 }
michael@0 406 };
michael@0 407
michael@0 408 /**
michael@0 409 * Global Tokens
michael@0 410 *
michael@0 411 * @see WAP-192-WBXML-20010725-A, clause 7.1
michael@0 412 */
michael@0 413 const WBXML_GLOBAL_TOKENS = (function () {
michael@0 414 let names = {};
michael@0 415 function add(number, coder) {
michael@0 416 let entry = {
michael@0 417 number: number,
michael@0 418 coder: coder,
michael@0 419 };
michael@0 420 names[number] = entry;
michael@0 421 }
michael@0 422
michael@0 423 add(CODE_PAGE_SWITCH_TOKEN, WbxmlCodePageSwitch);
michael@0 424 add(TAG_END_TOKEN, WbxmlEnd);
michael@0 425 add(INLINE_STRING_TOKEN, WbxmlInlineString);
michael@0 426 add(STRING_TABLE_TOKEN, WbxmlStringTable);
michael@0 427 add(OPAQUE_TOKEN, WbxmlOpaque);
michael@0 428
michael@0 429 return names;
michael@0 430 })();
michael@0 431
michael@0 432 /**
michael@0 433 * Pre-defined public IDs
michael@0 434 *
michael@0 435 * @see http://technical.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.aspx
michael@0 436 */
michael@0 437 const WBXML_PUBLIC_ID = (function () {
michael@0 438 let ids = {};
michael@0 439 function add(id, text) {
michael@0 440 ids[id] = text;
michael@0 441 }
michael@0 442
michael@0 443 // Well Known Values
michael@0 444 add(0x01, "UNKNOWN");
michael@0 445 add(0x02, "-//WAPFORUM//DTD WML 1.0//EN");
michael@0 446 add(0x03, "-//WAPFORUM//DTD WTA 1.0//EN");
michael@0 447 add(0x04, "-//WAPFORUM//DTD WML 1.1//EN");
michael@0 448 add(0x05, "-//WAPFORUM//DTD SI 1.0//EN");
michael@0 449 add(0x06, "-//WAPFORUM//DTD SL 1.0//EN");
michael@0 450 add(0x07, "-//WAPFORUM//DTD CO 1.0//EN");
michael@0 451 add(0x08, "-//WAPFORUM//DTD CHANNEL 1.1//EN");
michael@0 452 add(0x09, "-//WAPFORUM//DTD WML 1.2//EN");
michael@0 453 add(0x0A, "-//WAPFORUM//DTD WML 1.3//EN");
michael@0 454 add(0x0B, "-//WAPFORUM//DTD PROV 1.0//EN");
michael@0 455 add(0x0C, "-//WAPFORUM//DTD WTA-WML 1.2//EN");
michael@0 456 add(0x0D, "-//WAPFORUM//DTD EMN 1.0//EN");
michael@0 457 add(0x0E, "-//OMA//DTD DRMREL 1.0//EN");
michael@0 458 add(0x0F, "-//WIRELESSVILLAGE//DTD CSP 1.0//EN");
michael@0 459 add(0x10, "-//WIRELESSVILLAGE//DTD CSP 1.1//EN");
michael@0 460 add(0x11, "-//OMA//DTD WV-CSP 1.2//EN");
michael@0 461 add(0x12, "-//OMA//DTD IMPS-CSP 1.3//EN");
michael@0 462 add(0x13, "-//OMA//DRM 2.1//EN");
michael@0 463 add(0x14, "-//OMA//SRM 1.0//EN");
michael@0 464 add(0x15, "-//OMA//DCD 1.0//EN");
michael@0 465 add(0x16, "-//OMA//DTD DS-DataObjectEmail 1.2//EN");
michael@0 466 add(0x17, "-//OMA//DTD DS-DataObjectFolder 1.2//EN");
michael@0 467 add(0x18, "-//OMA//DTD DS-DataObjectFile 1.2//EN");
michael@0 468
michael@0 469 // Registered Values
michael@0 470 add(0x0FD1, "-//SYNCML//DTD SyncML 1.0//EN");
michael@0 471 add(0x0FD2, "-//SYNCML//DTD DevInf 1.0//EN");
michael@0 472 add(0x0FD3, "-//SYNCML//DTD SyncML 1.1//EN");
michael@0 473 add(0x0FD4, "-//SYNCML//DTD DevInf 1.1//EN");
michael@0 474 add(0x1100, "-//PHONE.COM//DTD ALERT 1.0//EN");
michael@0 475 add(0x1101, "-//PHONE.COM//DTD CACHE-OPERATION 1.0//EN");
michael@0 476 add(0x1102, "-//PHONE.COM//DTD SIGNAL 1.0//EN");
michael@0 477 add(0x1103, "-//PHONE.COM//DTD LIST 1.0//EN");
michael@0 478 add(0x1104, "-//PHONE.COM//DTD LISTCMD 1.0//EN");
michael@0 479 add(0x1105, "-//PHONE.COM//DTD CHANNEL 1.0//EN");
michael@0 480 add(0x1106, "-//PHONE.COM//DTD MMC 1.0//EN");
michael@0 481 add(0x1107, "-//PHONE.COM//DTD BEARER-CHOICE 1.0//EN");
michael@0 482 add(0x1108, "-//PHONE.COM//DTD WML 1.1//EN");
michael@0 483 add(0x1109, "-//PHONE.COM//DTD CHANNEL 1.1//EN");
michael@0 484 add(0x110A, "-//PHONE.COM//DTD LIST 1.1//EN");
michael@0 485 add(0x110B, "-//PHONE.COM//DTD LISTCMD 1.1//EN");
michael@0 486 add(0x110C, "-//PHONE.COM//DTD MMC 1.1//EN");
michael@0 487 add(0x110D, "-//PHONE.COM//DTD WML 1.3//EN");
michael@0 488 add(0x110E, "-//PHONE.COM//DTD MMC 2.0//EN");
michael@0 489 add(0x1200, "-//3GPP2.COM//DTD IOTA 1.0//EN");
michael@0 490 add(0x1201, "-//SYNCML//DTD SyncML 1.2//EN");
michael@0 491 add(0x1202, "-//SYNCML//DTD MetaInf 1.2//EN");
michael@0 492 add(0x1203, "-//SYNCML//DTD DevInf 1.2//EN");
michael@0 493 add(0x1204, "-//NOKIA//DTD LANDMARKS 1.0//EN");
michael@0 494 add(0x1205, "-//SyncML//Schema SyncML 2.0//EN");
michael@0 495 add(0x1206, "-//SyncML//Schema DevInf 2.0//EN");
michael@0 496 add(0x1207, "-//OMA//DTD DRMREL 1.0//EN");
michael@0 497
michael@0 498 return ids;
michael@0 499 })();
michael@0 500
michael@0 501 this.EXPORTED_SYMBOLS = [
michael@0 502 // Parser
michael@0 503 "PduHelper",
michael@0 504 ];

mercurial