Thu, 22 Jan 2015 13:21:57 +0100
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 += "&" ; break; |
michael@0 | 114 | case '<' : dst += "<" ; break; |
michael@0 | 115 | case '>' : dst += ">" ; break; |
michael@0 | 116 | case '"' : dst += """; break; |
michael@0 | 117 | case '\'': dst += "'"; 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 | ]; |