blob: 675a876ed85430939e76983c4a8159c8ccd1a087 [file] [log] [blame]
Wentao Shangbd63e462012-12-03 16:19:33 -08001/**
Jeff Thompson1b196592012-10-14 17:07:40 -07002 * This class is used to decode ccnb binary elements (blob, type/value pairs).
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07003 *
Jeff Thompson146d7de2012-11-17 16:15:28 -08004 * @author: Meki Cheraoui
Jeff Thompson745026e2012-10-13 12:49:20 -07005 * See COPYING for copyright and distribution information.
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07006 */
7
8var XML_EXT = 0x00;
9
10var XML_TAG = 0x01;
11
12var XML_DTAG = 0x02;
13
14var XML_ATTR = 0x03;
15
16var XML_DATTR = 0x04;
17
18var XML_BLOB = 0x05;
19
20var XML_UDATA = 0x06;
21
22var XML_CLOSE = 0x0;
23
24var XML_SUBTYPE_PROCESSING_INSTRUCTIONS = 16;
25
26
27var XML_TT_BITS = 3;
28var XML_TT_MASK = ((1 << XML_TT_BITS) - 1);
29var XML_TT_VAL_BITS = XML_TT_BITS + 1;
30var XML_TT_VAL_MASK = ((1 << (XML_TT_VAL_BITS)) - 1);
31var XML_REG_VAL_BITS = 7;
32var XML_REG_VAL_MASK = ((1 << XML_REG_VAL_BITS) - 1);
33var XML_TT_NO_MORE = (1 << XML_REG_VAL_BITS); // 0x80
34var BYTE_MASK = 0xFF;
35var LONG_BYTES = 8;
36var LONG_BITS = 64;
37
38var bits_11 = 0x0000007FF;
39var bits_18 = 0x00003FFFF;
40var bits_32 = 0x0FFFFFFFF;
41
42
43
44//returns a string
45tagToString = function(/*long*/ tagVal) {
46 if ((tagVal >= 0) && (tagVal < CCNProtocolDTagsStrings.length)) {
47 return CCNProtocolDTagsStrings[tagVal];
48 } else if (tagVal == CCNProtocolDTags.CCNProtocolDataUnit) {
49 return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT;
50 }
51 return null;
52};
53
54//returns a Long
55stringToTag = function(/*String*/ tagName) {
56 // the slow way, but right now we don't care.... want a static lookup for the forward direction
57 for (var i=0; i < CCNProtocolDTagsStrings.length; ++i) {
58 if ((null != CCNProtocolDTagsStrings[i]) && (CCNProtocolDTagsStrings[i] == tagName)) {
59 return i;
60 }
61 }
62 if (CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT == tagName) {
63 return CCNProtocolDTags.CCNProtocolDataUnit;
64 }
65 return null;
66};
67
Jeff Thompson2b14c7e2013-07-29 15:09:56 -070068/**
69 * @constructor
70 */
Jeff Thompson14afeea2013-06-24 16:23:30 -070071var BinaryXMLDecoder = function BinaryXMLDecoder(input){
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070072 var MARK_LEN=512;
73 var DEBUG_MAX_LEN = 32768;
74
Jeff Thompson14afeea2013-06-24 16:23:30 -070075 this.input = input;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070076 this.offset = 0;
77};
78
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070079BinaryXMLDecoder.prototype.initializeDecoding = function() {
Jeff Thompson14afeea2013-06-24 16:23:30 -070080 //if (!this.input.markSupported()) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070081 //throw new IllegalArgumentException(this.getClass().getName() + ": input stream must support marking!");
82 //}
83}
84
85BinaryXMLDecoder.prototype.readStartDocument = function(){
86 // Currently no start document in binary encoding.
87 }
88
89BinaryXMLDecoder.prototype.readEndDocument = function() {
90 // Currently no end document in binary encoding.
91 };
92
93BinaryXMLDecoder.prototype.readStartElement = function(
94 //String
95 startTag,
96 //TreeMap<String, String>
97 attributes) {
98
99
100 //NOT SURE
101 //if(typeof startTag == 'number')
102 //startTag = tagToString(startTag);
103
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700104 //TypeAndVal
Jeff Thompsonc3c611b2013-02-18 22:52:03 -0800105 var tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700106
107 if (null == tv) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700108 throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got something not a tag."));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700109 }
110
111 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800112 var decodedTag = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700113 //console.log(tv);
114 //console.log(typeof tv);
115
116 //console.log(XML_TAG);
117 if (tv.type() == XML_TAG) {
118 //console.log('got here');
119 //Log.info(Log.FAC_ENCODING, "Unexpected: got tag in readStartElement; looking for tag " + startTag + " got length: " + (int)tv.val()+1);
120 // Tag value represents length-1 as tags can never be empty.
121 var valval ;
122 if(typeof tv.val() == 'string'){
123 valval = (parseInt(tv.val())) + 1;
124 }
125 else
126 valval = (tv.val())+ 1;
127
128 //console.log('valval is ' +valval);
129
Jeff Thompson1b196592012-10-14 17:07:40 -0700130 decodedTag = this.decodeUString(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700131
132 } else if (tv.type() == XML_DTAG) {
133 //console.log('gothere');
134 //console.log(tv.val());
135 //decodedTag = tagToString(tv.val());
136 //console.log()
137 decodedTag = tv.val();
138 }
139
140 //console.log(decodedTag);
141 //console.log('startTag is '+startTag);
142
143
144 if ((null == decodedTag) || decodedTag != startTag ) {
Jeff Thompsonb7e190b2012-11-28 18:38:15 -0800145 console.log('expecting '+ startTag + ' but got '+ decodedTag);
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700146 throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got: " + decodedTag + "(" + tv.val() + ")"));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700147 }
148
149 // DKS: does not read attributes out of stream if caller doesn't
150 // ask for them. Should possibly peek and skip over them regardless.
151 // TODO: fix this
152 if (null != attributes) {
153 readAttributes(attributes);
154 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700155 }
156
157
158BinaryXMLDecoder.prototype.readAttributes = function(
Jeff Thompsonc3c611b2013-02-18 22:52:03 -0800159 // array of [attributeName, attributeValue]
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700160 attributes) {
161
162 if (null == attributes) {
163 return;
164 }
165
166 try {
167 // Now need to get attributes.
168 //TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800169 var nextTV = this.peekTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700170
171 while ((null != nextTV) && ((XML_ATTR == nextTV.type()) ||
172 (XML_DATTR == nextTV.type()))) {
173
174 // Decode this attribute. First, really read the type and value.
175 //this.TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800176 var thisTV = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700177
178 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800179 var attributeName = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700180 if (XML_ATTR == thisTV.type()) {
181 // Tag value represents length-1 as attribute names cannot be empty.
182 var valval ;
Jeff Thompsonc3c611b2013-02-18 22:52:03 -0800183 if(typeof thisTV.val() == 'string'){
184 valval = (parseInt(thisTV.val())) + 1;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700185 }
186 else
Jeff Thompsonc3c611b2013-02-18 22:52:03 -0800187 valval = (thisTV.val())+ 1;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700188
Jeff Thompson1b196592012-10-14 17:07:40 -0700189 attributeName = this.decodeUString(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700190
191 } else if (XML_DATTR == thisTV.type()) {
192 // DKS TODO are attributes same or different dictionary?
193 attributeName = tagToString(thisTV.val());
194 if (null == attributeName) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700195 throw new ContentDecodingException(new Error("Unknown DATTR value" + thisTV.val()));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700196 }
197 }
198 // Attribute values are always UDATA
199 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800200 var attributeValue = this.decodeUString();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700201
202 //
203 attributes.push([attributeName, attributeValue]);
204
Jeff Thompson1b196592012-10-14 17:07:40 -0700205 nextTV = this.peekTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700206 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700207 } catch ( e) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700208 throw new ContentDecodingException(new Error("readStartElement", e));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700209 }
210};
211
212//returns a string
213BinaryXMLDecoder.prototype.peekStartElementAsString = function() {
Jeff Thompson14afeea2013-06-24 16:23:30 -0700214 //this.input.mark(MARK_LEN);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700215
216 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800217 var decodedTag = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700218 var previousOffset = this.offset;
219 try {
220 // Have to distinguish genuine errors from wrong tags. Could either use
221 // a special exception subtype, or redo the work here.
222 //this.TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800223 var tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700224
225 if (null != tv) {
226
227 if (tv.type() == XML_TAG) {
228 /*if (tv.val()+1 > DEBUG_MAX_LEN) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700229 throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!")(;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700230 }*/
231
232 // Tag value represents length-1 as tags can never be empty.
233 var valval ;
234 if(typeof tv.val() == 'string'){
235 valval = (parseInt(tv.val())) + 1;
236 }
237 else
238 valval = (tv.val())+ 1;
239
Jeff Thompson1b196592012-10-14 17:07:40 -0700240 decodedTag = this.decodeUString(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700241
242 //Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
243
244 } else if (tv.type() == XML_DTAG) {
245 decodedTag = tagToString(tv.val());
246 }
247
248 } // else, not a type and val, probably an end element. rewind and return false.
249
250 } catch ( e) {
251
252 } finally {
253 try {
254 this.offset = previousOffset;
255 } catch ( e) {
256 Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700257 throw new ContentDecodingException(new Error("Cannot reset stream! " + e.getMessage(), e));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700258 }
259 }
260 return decodedTag;
261};
262
263BinaryXMLDecoder.prototype.peekStartElement = function(
264 //String
265 startTag) {
266 //String
267 if(typeof startTag == 'string'){
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800268 var decodedTag = this.peekStartElementAsString();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700269
270 if ((null != decodedTag) && decodedTag == startTag) {
271 return true;
272 }
273 return false;
274 }
275 else if(typeof startTag == 'number'){
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800276 var decodedTag = this.peekStartElementAsLong();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700277 if ((null != decodedTag) && decodedTag == startTag) {
278 return true;
279 }
280 return false;
281 }
282 else{
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700283 throw new ContentDecodingException(new Error("SHOULD BE STRING OR NUMBER"));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700284 }
285}
286//returns Long
287BinaryXMLDecoder.prototype.peekStartElementAsLong = function() {
Jeff Thompson14afeea2013-06-24 16:23:30 -0700288 //this.input.mark(MARK_LEN);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700289
290 //Long
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800291 var decodedTag = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700292
293 var previousOffset = this.offset;
294
295 try {
296 // Have to distinguish genuine errors from wrong tags. Could either use
297 // a special exception subtype, or redo the work here.
298 //this.TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800299 var tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700300
301 if (null != tv) {
302
303 if (tv.type() == XML_TAG) {
304 if (tv.val()+1 > DEBUG_MAX_LEN) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700305 throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!"));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700306 }
307
308 var valval ;
309 if(typeof tv.val() == 'string'){
310 valval = (parseInt(tv.val())) + 1;
311 }
312 else
313 valval = (tv.val())+ 1;
314
315 // Tag value represents length-1 as tags can never be empty.
316 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800317 var strTag = this.decodeUString(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700318
319 decodedTag = stringToTag(strTag);
320
321 //Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
322
323 } else if (tv.type() == XML_DTAG) {
324 decodedTag = tv.val();
325 }
326
327 } // else, not a type and val, probably an end element. rewind and return false.
328
329 } catch ( e) {
330
331 } finally {
332 try {
Jeff Thompson14afeea2013-06-24 16:23:30 -0700333 //this.input.reset();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700334 this.offset = previousOffset;
335 } catch ( e) {
336 Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
Jeff Thompson34a2ec02012-09-29 21:47:05 -0700337 throw new Error("Cannot reset stream! " + e.getMessage(), e);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700338 }
339 }
340 return decodedTag;
341 };
342
343
Jeff Thompsonefff43b2013-03-10 17:10:26 -0700344// Returns a Uint8Array.
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700345BinaryXMLDecoder.prototype.readBinaryElement = function(
346 //long
347 startTag,
348 //TreeMap<String, String>
Jeff Thompsond4a1f862013-03-10 17:30:31 -0700349 attributes,
350 //boolean
351 allowNull){
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800352 this.readStartElement(startTag, attributes);
Jeff Thompsond4a1f862013-03-10 17:30:31 -0700353 return this.readBlob(allowNull);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700354};
355
356
357BinaryXMLDecoder.prototype.readEndElement = function(){
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700358 if(LOG>4)console.log('this.offset is '+this.offset);
359
Jeff Thompson14afeea2013-06-24 16:23:30 -0700360 var next = this.input[this.offset];
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700361
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700362 this.offset++;
363 //read();
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700364
365 if(LOG>4)console.log('XML_CLOSE IS '+XML_CLOSE);
366 if(LOG>4)console.log('next is '+next);
367
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700368 if (next != XML_CLOSE) {
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700369 console.log("Expected end element, got: " + next);
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700370 throw new ContentDecodingException(new Error("Expected end element, got: " + next));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700371 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700372 };
373
374
375//String
376BinaryXMLDecoder.prototype.readUString = function(){
377 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800378 var ustring = this.decodeUString();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700379 this.readEndElement();
380 return ustring;
381
382 };
383
384
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700385/**
Jeff Thompsond4a1f862013-03-10 17:30:31 -0700386 * Read a blob as well as the end element. Returns a Uint8Array (or null for missing blob).
387 * If the blob is missing and allowNull is false (default), throw an exception. Otherwise,
388 * just read the end element and return null.
389 */
390BinaryXMLDecoder.prototype.readBlob = function(allowNull) {
Jeff Thompson14afeea2013-06-24 16:23:30 -0700391 if (this.input[this.offset] == XML_CLOSE && allowNull) {
Jeff Thompsond4a1f862013-03-10 17:30:31 -0700392 this.readEndElement();
393 return null;
394 }
395
Jeff Thompsonefff43b2013-03-10 17:10:26 -0700396 var blob = this.decodeBlob();
397 this.readEndElement();
398 return blob;
399};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700400
401
402//CCNTime
403BinaryXMLDecoder.prototype.readDateTime = function(
404 //long
405 startTag) {
406 //byte []
407
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700408 var byteTimestamp = this.readBinaryElement(startTag);
409
410 //var lontimestamp = DataUtils.byteArrayToUnsignedLong(byteTimestamp);
411
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800412 byteTimestamp = DataUtils.toHex(byteTimestamp);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700413
414
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800415 byteTimestamp = parseInt(byteTimestamp, 16);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700416
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800417 var lontimestamp = (byteTimestamp/ 4096) * 1000;
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700418
419 //if(lontimestamp<0) lontimestamp = - lontimestamp;
420
Jeff Thompson0da65612013-03-10 16:30:27 -0700421 if(LOG>4) console.log('DECODED DATE WITH VALUE');
422 if(LOG>4) console.log(lontimestamp);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700423
424
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700425 //CCNTime
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800426 var timestamp = new CCNTime(lontimestamp);
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700427 //timestamp.setDateBinary(byteTimestamp);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700428
429 if (null == timestamp) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700430 throw new ContentDecodingException(new Error("Cannot parse timestamp: " + DataUtils.printHexBytes(byteTimestamp)));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700431 }
432 return timestamp;
433};
434
Jeff Thompson1b196592012-10-14 17:07:40 -0700435BinaryXMLDecoder.prototype.decodeTypeAndVal = function() {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700436
Jeff Thompsonf72d7ed2012-10-25 20:57:07 -0700437 /*int*/var type = -1;
438 /*long*/var val = 0;
439 /*boolean*/var more = true;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700440
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700441 do {
442
Jeff Thompson14afeea2013-06-24 16:23:30 -0700443 var next = this.input[this.offset ];
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700444
445
446 if (next < 0) {
447 return null;
448 }
449
450 if ((0 == next) && (0 == val)) {
451 return null;
452 }
453
454 more = (0 == (next & XML_TT_NO_MORE));
455
456 if (more) {
457 val = val << XML_REG_VAL_BITS;
458 val |= (next & XML_REG_VAL_MASK);
459 } else {
460
461 type = next & XML_TT_MASK;
462 val = val << XML_TT_VAL_BITS;
463 val |= ((next >>> XML_TT_BITS) & XML_TT_VAL_MASK);
464 }
465
466 this.offset++;
467
468 } while (more);
469
Jeff Thompson0da65612013-03-10 16:30:27 -0700470 if(LOG>4)console.log('TYPE is '+ type + ' VAL is '+ val);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700471
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700472 return new TypeAndVal(type, val);
473};
474
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700475//TypeAndVal
Jeff Thompson7480aca2013-03-10 16:01:33 -0700476BinaryXMLDecoder.prototype.peekTypeAndVal = function() {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700477 //TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800478 var tv = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700479 var previousOffset = this.offset;
480
481 try {
Jeff Thompson1b196592012-10-14 17:07:40 -0700482 tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700483 } finally {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700484 this.offset = previousOffset;
485 }
486
487 return tv;
488};
489
Jeff Thompsonc92706b2012-11-11 19:12:58 -0800490//Uint8Array
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700491BinaryXMLDecoder.prototype.decodeBlob = function(
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700492 //int
493 blobLength) {
494
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700495 if(null == blobLength){
496 //TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800497 var tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700498
499 var valval ;
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700500
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700501 if(typeof tv.val() == 'string'){
502 valval = (parseInt(tv.val()));
503 }
504 else
505 valval = (tv.val());
506
507 //console.log('valval here is ' + valval);
Jeff Thompson1b196592012-10-14 17:07:40 -0700508 return this.decodeBlob(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700509 }
510
511 //
Jeff Thompsonc92706b2012-11-11 19:12:58 -0800512 //Uint8Array
Jeff Thompson14afeea2013-06-24 16:23:30 -0700513 var bytes = this.input.subarray(this.offset, this.offset+ blobLength);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700514 this.offset += blobLength;
515
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700516 return bytes;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700517};
518
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700519//String
520BinaryXMLDecoder.prototype.decodeUString = function(
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700521 //int
522 byteLength) {
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700523 if(null == byteLength ){
524 var tempStreamPosition = this.offset;
525
526 //TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800527 var tv = this.decodeTypeAndVal();
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700528
Jeff Thompson0da65612013-03-10 16:30:27 -0700529 if(LOG>4)console.log('TV is '+tv);
530 if(LOG>4)console.log(tv);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700531
Jeff Thompson0da65612013-03-10 16:30:27 -0700532 if(LOG>4)console.log('Type of TV is '+typeof tv);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700533
534 if ((null == tv) || (XML_UDATA != tv.type())) { // if we just have closers left, will get back null
535 //if (Log.isLoggable(Log.FAC_ENCODING, Level.FINEST))
536 //Log.finest(Log.FAC_ENCODING, "Expected UDATA, got " + ((null == tv) ? " not a tag " : tv.type()) + ", assuming elided 0-length blob.");
537
538 this.offset = tempStreamPosition;
539
540 return "";
541 }
542
Jeff Thompson1b196592012-10-14 17:07:40 -0700543 return this.decodeUString(tv.val());
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700544 }
545 else{
Wentao Shang882e34e2013-01-05 02:49:51 -0800546 //uint8array
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800547 var stringBytes = this.decodeBlob(byteLength);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700548
549 //return DataUtils.getUTF8StringFromBytes(stringBytes);
550 return DataUtils.toString(stringBytes);
551
552 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700553};
554
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700555//OBject containg a pair of type and value
556var TypeAndVal = function TypeAndVal(_type,_val) {
557 this.t = _type;
558 this.v = _val;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700559};
560
561TypeAndVal.prototype.type = function(){
562 return this.t;
563};
564
565TypeAndVal.prototype.val = function(){
566 return this.v;
567};
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700568
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700569BinaryXMLDecoder.prototype.readIntegerElement =function(
570 //String
571 startTag) {
572
573 //String
574 if(LOG>4) console.log('READING INTEGER '+ startTag);
575 if(LOG>4) console.log('TYPE OF '+ typeof startTag);
576
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800577 var strVal = this.readUTF8Element(startTag);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700578
579 return parseInt(strVal);
580};
581
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700582BinaryXMLDecoder.prototype.readUTF8Element =function(
583 //String
584 startTag,
585 //TreeMap<String, String>
586 attributes) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700587 //throws Error where name == "ContentDecodingException"
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700588
589 this.readStartElement(startTag, attributes); // can't use getElementText, can't get attributes
590 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800591 var strElementText = this.readUString();
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700592 return strElementText;
593};
Jeff Thompson1b196592012-10-14 17:07:40 -0700594
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700595/**
Jeff Thompson1b196592012-10-14 17:07:40 -0700596 * Set the offset into the input, used for the next read.
597 */
598BinaryXMLDecoder.prototype.seek = function(
599 //int
600 offset) {
Jeff Thompsonc92706b2012-11-11 19:12:58 -0800601 this.offset = offset;
Jeff Thompson1b196592012-10-14 17:07:40 -0700602}
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700603
604/*
605 * Call with: throw new ContentDecodingException(new Error("message")).
606 */
607function ContentDecodingException(error) {
608 this.message = error.message;
609 // Copy lineNumber, etc. from where new Error was called.
610 for (var prop in error)
611 this[prop] = error[prop];
612}
613ContentDecodingException.prototype = new Error();
614ContentDecodingException.prototype.name = "ContentDecodingException";
615