blob: 4f516d689305a856976526d5ca7202f635defacf [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
68//console.log(stringToTag(64));
69var BinaryXMLDecoder = function BinaryXMLDecoder(istream){
70 var MARK_LEN=512;
71 var DEBUG_MAX_LEN = 32768;
72
73 this.istream = istream;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070074 this.offset = 0;
75};
76
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070077BinaryXMLDecoder.prototype.readAttributes = function(
78 //TreeMap<String,String>
79 attributes){
80
81 if (null == attributes) {
82 return;
83 }
84
85 try {
86
87 //this.TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -080088 var nextTV = this.peekTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070089
90 while ((null != nextTV) && ((XML_ATTR == nextTV.type()) ||
91 (XML_DATTR == nextTV.type()))) {
92
93 //this.TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -080094 var thisTV = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070095
96 var attributeName = null;
97 if (XML_ATTR == thisTV.type()) {
98
Jeff Thompson1b196592012-10-14 17:07:40 -070099 attributeName = this.decodeUString(thisTV.val()+1);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700100
101 } else if (XML_DATTR == thisTV.type()) {
102 // DKS TODO are attributes same or different dictionary?
103 attributeName = tagToString(thisTV.val());
104 if (null == attributeName) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700105 throw new ContentDecodingException(new Error("Unknown DATTR value" + thisTV.val()));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700106 }
107 }
108
Jeff Thompson1b196592012-10-14 17:07:40 -0700109 var attributeValue = this.decodeUString();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700110
111 attributes.put(attributeName, attributeValue);
112
Jeff Thompson1b196592012-10-14 17:07:40 -0700113 nextTV = this.peekTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700114 }
115
116 } catch ( e) {
117
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700118 throw new ContentDecodingException(new Error("readStartElement", e));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700119 }
120};
121
122
123BinaryXMLDecoder.prototype.initializeDecoding = function() {
124 //if (!this.istream.markSupported()) {
125 //throw new IllegalArgumentException(this.getClass().getName() + ": input stream must support marking!");
126 //}
127}
128
129BinaryXMLDecoder.prototype.readStartDocument = function(){
130 // Currently no start document in binary encoding.
131 }
132
133BinaryXMLDecoder.prototype.readEndDocument = function() {
134 // Currently no end document in binary encoding.
135 };
136
137BinaryXMLDecoder.prototype.readStartElement = function(
138 //String
139 startTag,
140 //TreeMap<String, String>
141 attributes) {
142
143
144 //NOT SURE
145 //if(typeof startTag == 'number')
146 //startTag = tagToString(startTag);
147
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700148 //TypeAndVal
Jeff Thompson1b196592012-10-14 17:07:40 -0700149 tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700150
151 if (null == tv) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700152 throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got something not a tag."));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700153 }
154
155 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800156 var decodedTag = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700157 //console.log(tv);
158 //console.log(typeof tv);
159
160 //console.log(XML_TAG);
161 if (tv.type() == XML_TAG) {
162 //console.log('got here');
163 //Log.info(Log.FAC_ENCODING, "Unexpected: got tag in readStartElement; looking for tag " + startTag + " got length: " + (int)tv.val()+1);
164 // Tag value represents length-1 as tags can never be empty.
165 var valval ;
166 if(typeof tv.val() == 'string'){
167 valval = (parseInt(tv.val())) + 1;
168 }
169 else
170 valval = (tv.val())+ 1;
171
172 //console.log('valval is ' +valval);
173
Jeff Thompson1b196592012-10-14 17:07:40 -0700174 decodedTag = this.decodeUString(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700175
176 } else if (tv.type() == XML_DTAG) {
177 //console.log('gothere');
178 //console.log(tv.val());
179 //decodedTag = tagToString(tv.val());
180 //console.log()
181 decodedTag = tv.val();
182 }
183
184 //console.log(decodedTag);
185 //console.log('startTag is '+startTag);
186
187
188 if ((null == decodedTag) || decodedTag != startTag ) {
Jeff Thompsonb7e190b2012-11-28 18:38:15 -0800189 console.log('expecting '+ startTag + ' but got '+ decodedTag);
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700190 throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got: " + decodedTag + "(" + tv.val() + ")"));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700191 }
192
193 // DKS: does not read attributes out of stream if caller doesn't
194 // ask for them. Should possibly peek and skip over them regardless.
195 // TODO: fix this
196 if (null != attributes) {
197 readAttributes(attributes);
198 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700199 }
200
201
202BinaryXMLDecoder.prototype.readAttributes = function(
203 //TreeMap<String,String>
204 attributes) {
205
206 if (null == attributes) {
207 return;
208 }
209
210 try {
211 // Now need to get attributes.
212 //TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800213 var nextTV = this.peekTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700214
215 while ((null != nextTV) && ((XML_ATTR == nextTV.type()) ||
216 (XML_DATTR == nextTV.type()))) {
217
218 // Decode this attribute. First, really read the type and value.
219 //this.TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800220 var thisTV = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700221
222 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800223 var attributeName = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700224 if (XML_ATTR == thisTV.type()) {
225 // Tag value represents length-1 as attribute names cannot be empty.
226 var valval ;
227 if(typeof tv.val() == 'string'){
228 valval = (parseInt(tv.val())) + 1;
229 }
230 else
231 valval = (tv.val())+ 1;
232
Jeff Thompson1b196592012-10-14 17:07:40 -0700233 attributeName = this.decodeUString(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700234
235 } else if (XML_DATTR == thisTV.type()) {
236 // DKS TODO are attributes same or different dictionary?
237 attributeName = tagToString(thisTV.val());
238 if (null == attributeName) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700239 throw new ContentDecodingException(new Error("Unknown DATTR value" + thisTV.val()));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700240 }
241 }
242 // Attribute values are always UDATA
243 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800244 var attributeValue = this.decodeUString();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700245
246 //
247 attributes.push([attributeName, attributeValue]);
248
Jeff Thompson1b196592012-10-14 17:07:40 -0700249 nextTV = this.peekTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700250 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700251 } catch ( e) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700252 throw new ContentDecodingException(new Error("readStartElement", e));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700253 }
254};
255
256//returns a string
257BinaryXMLDecoder.prototype.peekStartElementAsString = function() {
258 //this.istream.mark(MARK_LEN);
259
260 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800261 var decodedTag = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700262 var previousOffset = this.offset;
263 try {
264 // Have to distinguish genuine errors from wrong tags. Could either use
265 // a special exception subtype, or redo the work here.
266 //this.TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800267 var tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700268
269 if (null != tv) {
270
271 if (tv.type() == XML_TAG) {
272 /*if (tv.val()+1 > DEBUG_MAX_LEN) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700273 throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!")(;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700274 }*/
275
276 // Tag value represents length-1 as tags can never be empty.
277 var valval ;
278 if(typeof tv.val() == 'string'){
279 valval = (parseInt(tv.val())) + 1;
280 }
281 else
282 valval = (tv.val())+ 1;
283
Jeff Thompson1b196592012-10-14 17:07:40 -0700284 decodedTag = this.decodeUString(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700285
286 //Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
287
288 } else if (tv.type() == XML_DTAG) {
289 decodedTag = tagToString(tv.val());
290 }
291
292 } // else, not a type and val, probably an end element. rewind and return false.
293
294 } catch ( e) {
295
296 } finally {
297 try {
298 this.offset = previousOffset;
299 } catch ( e) {
300 Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700301 throw new ContentDecodingException(new Error("Cannot reset stream! " + e.getMessage(), e));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700302 }
303 }
304 return decodedTag;
305};
306
307BinaryXMLDecoder.prototype.peekStartElement = function(
308 //String
309 startTag) {
310 //String
311 if(typeof startTag == 'string'){
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800312 var decodedTag = this.peekStartElementAsString();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700313
314 if ((null != decodedTag) && decodedTag == startTag) {
315 return true;
316 }
317 return false;
318 }
319 else if(typeof startTag == 'number'){
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800320 var decodedTag = this.peekStartElementAsLong();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700321 if ((null != decodedTag) && decodedTag == startTag) {
322 return true;
323 }
324 return false;
325 }
326 else{
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700327 throw new ContentDecodingException(new Error("SHOULD BE STRING OR NUMBER"));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700328 }
329}
330//returns Long
331BinaryXMLDecoder.prototype.peekStartElementAsLong = function() {
332 //this.istream.mark(MARK_LEN);
333
334 //Long
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800335 var decodedTag = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700336
337 var previousOffset = this.offset;
338
339 try {
340 // Have to distinguish genuine errors from wrong tags. Could either use
341 // a special exception subtype, or redo the work here.
342 //this.TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800343 var tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700344
345 if (null != tv) {
346
347 if (tv.type() == XML_TAG) {
348 if (tv.val()+1 > DEBUG_MAX_LEN) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700349 throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!"));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700350 }
351
352 var valval ;
353 if(typeof tv.val() == 'string'){
354 valval = (parseInt(tv.val())) + 1;
355 }
356 else
357 valval = (tv.val())+ 1;
358
359 // Tag value represents length-1 as tags can never be empty.
360 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800361 var strTag = this.decodeUString(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700362
363 decodedTag = stringToTag(strTag);
364
365 //Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
366
367 } else if (tv.type() == XML_DTAG) {
368 decodedTag = tv.val();
369 }
370
371 } // else, not a type and val, probably an end element. rewind and return false.
372
373 } catch ( e) {
374
375 } finally {
376 try {
377 //this.istream.reset();
378 this.offset = previousOffset;
379 } catch ( e) {
380 Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
Jeff Thompson34a2ec02012-09-29 21:47:05 -0700381 throw new Error("Cannot reset stream! " + e.getMessage(), e);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700382 }
383 }
384 return decodedTag;
385 };
386
387
388// returns a byte[]
389BinaryXMLDecoder.prototype.readBinaryElement = function(
390 //long
391 startTag,
392 //TreeMap<String, String>
393 attributes){
394 //byte []
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800395 var blob = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700396
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800397 this.readStartElement(startTag, attributes);
398 blob = this.readBlob();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700399
400 return blob;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700401};
402
403
404BinaryXMLDecoder.prototype.readEndElement = function(){
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700405 if(LOG>4)console.log('this.offset is '+this.offset);
406
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700407 var next = this.istream[this.offset];
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700408
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700409 this.offset++;
410 //read();
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700411
412 if(LOG>4)console.log('XML_CLOSE IS '+XML_CLOSE);
413 if(LOG>4)console.log('next is '+next);
414
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700415 if (next != XML_CLOSE) {
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700416 console.log("Expected end element, got: " + next);
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700417 throw new ContentDecodingException(new Error("Expected end element, got: " + next));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700418 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700419 };
420
421
422//String
423BinaryXMLDecoder.prototype.readUString = function(){
424 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800425 var ustring = this.decodeUString();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700426 this.readEndElement();
427 return ustring;
428
429 };
430
431
432//returns a byte[]
433BinaryXMLDecoder.prototype.readBlob = function() {
434 //byte []
435
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800436 var blob = this.decodeBlob();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700437 this.readEndElement();
438 return blob;
439
440 };
441
442
443//CCNTime
444BinaryXMLDecoder.prototype.readDateTime = function(
445 //long
446 startTag) {
447 //byte []
448
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700449 var byteTimestamp = this.readBinaryElement(startTag);
450
451 //var lontimestamp = DataUtils.byteArrayToUnsignedLong(byteTimestamp);
452
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800453 byteTimestamp = DataUtils.toHex(byteTimestamp);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700454
455
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800456 byteTimestamp = parseInt(byteTimestamp, 16);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700457
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800458 var lontimestamp = (byteTimestamp/ 4096) * 1000;
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700459
460 //if(lontimestamp<0) lontimestamp = - lontimestamp;
461
462 if(LOG>3) console.log('DECODED DATE WITH VALUE');
463 if(LOG>3) console.log(lontimestamp);
464
465
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700466 //CCNTime
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800467 var timestamp = new CCNTime(lontimestamp);
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700468 //timestamp.setDateBinary(byteTimestamp);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700469
470 if (null == timestamp) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700471 throw new ContentDecodingException(new Error("Cannot parse timestamp: " + DataUtils.printHexBytes(byteTimestamp)));
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700472 }
473 return timestamp;
474};
475
Jeff Thompson1b196592012-10-14 17:07:40 -0700476BinaryXMLDecoder.prototype.decodeTypeAndVal = function() {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700477
Jeff Thompsonf72d7ed2012-10-25 20:57:07 -0700478 /*int*/var type = -1;
479 /*long*/var val = 0;
480 /*boolean*/var more = true;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700481
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700482 do {
483
484 var next = this.istream[this.offset ];
485
486
487 if (next < 0) {
488 return null;
489 }
490
491 if ((0 == next) && (0 == val)) {
492 return null;
493 }
494
495 more = (0 == (next & XML_TT_NO_MORE));
496
497 if (more) {
498 val = val << XML_REG_VAL_BITS;
499 val |= (next & XML_REG_VAL_MASK);
500 } else {
501
502 type = next & XML_TT_MASK;
503 val = val << XML_TT_VAL_BITS;
504 val |= ((next >>> XML_TT_BITS) & XML_TT_VAL_MASK);
505 }
506
507 this.offset++;
508
509 } while (more);
510
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700511 if(LOG>3)console.log('TYPE is '+ type + ' VAL is '+ val);
512
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700513 return new TypeAndVal(type, val);
514};
515
516
517
518//TypeAndVal
Jeff Thompson1b196592012-10-14 17:07:40 -0700519BinaryXMLDecoder.peekTypeAndVal = function() {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700520 //TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800521 var tv = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700522
Jeff Thompson1b196592012-10-14 17:07:40 -0700523 //this.istream.mark(LONG_BYTES*2);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700524
525 var previousOffset = this.offset;
526
527 try {
Jeff Thompson1b196592012-10-14 17:07:40 -0700528 tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700529 } finally {
Jeff Thompson1b196592012-10-14 17:07:40 -0700530 //this.istream.reset();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700531 this.offset = previousOffset;
532 }
533
534 return tv;
535};
536
537
Jeff Thompsonc92706b2012-11-11 19:12:58 -0800538//Uint8Array
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700539BinaryXMLDecoder.prototype.decodeBlob = function(
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700540 //int
541 blobLength) {
542
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700543 if(null == blobLength){
544 //TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800545 var tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700546
547 var valval ;
Meki Cherkaouib21911b2012-05-18 16:54:37 -0700548
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700549 if(typeof tv.val() == 'string'){
550 valval = (parseInt(tv.val()));
551 }
552 else
553 valval = (tv.val());
554
555 //console.log('valval here is ' + valval);
Jeff Thompson1b196592012-10-14 17:07:40 -0700556 return this.decodeBlob(valval);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700557 }
558
559 //
Jeff Thompsonc92706b2012-11-11 19:12:58 -0800560 //Uint8Array
561 var bytes = this.istream.subarray(this.offset, this.offset+ blobLength);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700562 this.offset += blobLength;
563
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700564 return bytes;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700565};
566
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700567var count =0;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700568
569//String
570BinaryXMLDecoder.prototype.decodeUString = function(
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700571 //int
572 byteLength) {
573
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700574 /*
575 console.log('COUNT IS '+count);
576 console.log('INPUT BYTELENGTH IS '+byteLength);
577 count++;
578 if(null == byteLength|| undefined == byteLength){
579 console.log("!!!!");
Jeff Thompson1b196592012-10-14 17:07:40 -0700580 tv = this.decodeTypeAndVal();
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700581 var valval ;
582 if(typeof tv.val() == 'string'){
583 valval = (parseInt(tv.val()));
584 }
585 else
586 valval = (tv.val());
587
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700588 if(LOG>4) console.log('valval is ' + valval);
Jeff Thompson1b196592012-10-14 17:07:40 -0700589 byteLength= this.decodeUString(valval);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700590
591 //if(LOG>4) console.log('byte Length found in type val is '+ byteLength.charCodeAt(0));
592 byteLength = parseInt(byteLength);
593
594
595 //byteLength = byteLength.charCodeAt(0);
596 //if(LOG>4) console.log('byte Length found in type val is '+ byteLength);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700597 }
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700598 if(LOG>4)console.log('byteLength is '+byteLength);
599 if(LOG>4)console.log('type of byteLength is '+typeof byteLength);
600
Jeff Thompson1b196592012-10-14 17:07:40 -0700601 stringBytes = this.decodeBlob(byteLength);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700602
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700603 //console.log('String bytes are '+ stringBytes);
604 //console.log('stringBytes);
605
606 if(LOG>4)console.log('byteLength is '+byteLength);
607 if(LOG>4)console.log('this.offset is '+this.offset);
608
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700609 tempBuffer = this.istream.slice(this.offset, this.offset+byteLength);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700610 if(LOG>4)console.log('TEMPBUFFER IS' + tempBuffer);
611 if(LOG>4)console.log( tempBuffer);
612
613 if(LOG>4)console.log('ADDING to offset value' + byteLength);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700614 this.offset+= byteLength;
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700615 //if(LOG>3)console.log('read the String' + tempBuffer.toString('ascii'));
616 //return tempBuffer.toString('ascii');//
617
618
619 //if(LOG>3)console.log( 'STRING READ IS '+ DataUtils.getUTF8StringFromBytes(stringBytes) ) ;
620 //if(LOG>3)console.log( 'STRING READ IS '+ DataUtils.getUTF8StringFromBytes(tempBuffer) ) ;
621 //if(LOG>3)console.log(DataUtils.getUTF8StringFromBytes(tempBuffer) ) ;
622 //return DataUtils.getUTF8StringFromBytes(tempBuffer);
623
624 if(LOG>3)console.log( 'STRING READ IS '+ DataUtils.toString(stringBytes) ) ;
625 if(LOG>3)console.log( 'TYPE OF STRING READ IS '+ typeof DataUtils.toString(stringBytes) ) ;
626
627 return DataUtils.toString(stringBytes);*/
628
629 if(null == byteLength ){
630 var tempStreamPosition = this.offset;
631
632 //TypeAndVal
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800633 var tv = this.decodeTypeAndVal();
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700634
635 if(LOG>3)console.log('TV is '+tv);
636 if(LOG>3)console.log(tv);
637
638 if(LOG>3)console.log('Type of TV is '+typeof tv);
639
640 if ((null == tv) || (XML_UDATA != tv.type())) { // if we just have closers left, will get back null
641 //if (Log.isLoggable(Log.FAC_ENCODING, Level.FINEST))
642 //Log.finest(Log.FAC_ENCODING, "Expected UDATA, got " + ((null == tv) ? " not a tag " : tv.type()) + ", assuming elided 0-length blob.");
643
644 this.offset = tempStreamPosition;
645
646 return "";
647 }
648
Jeff Thompson1b196592012-10-14 17:07:40 -0700649 return this.decodeUString(tv.val());
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700650 }
651 else{
652 //byte []
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800653 var stringBytes = this.decodeBlob(byteLength);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700654
655 //return DataUtils.getUTF8StringFromBytes(stringBytes);
656 return DataUtils.toString(stringBytes);
657
658 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700659};
660
661
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700662
663
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700664//OBject containg a pair of type and value
665var TypeAndVal = function TypeAndVal(_type,_val) {
666 this.t = _type;
667 this.v = _val;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700668};
669
670TypeAndVal.prototype.type = function(){
671 return this.t;
672};
673
674TypeAndVal.prototype.val = function(){
675 return this.v;
676};
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700677
678
679
680
681BinaryXMLDecoder.prototype.readIntegerElement =function(
682 //String
683 startTag) {
684
685 //String
686 if(LOG>4) console.log('READING INTEGER '+ startTag);
687 if(LOG>4) console.log('TYPE OF '+ typeof startTag);
688
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800689 var strVal = this.readUTF8Element(startTag);
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700690
691 return parseInt(strVal);
692};
693
694
695BinaryXMLDecoder.prototype.readUTF8Element =function(
696 //String
697 startTag,
698 //TreeMap<String, String>
699 attributes) {
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700700 //throws Error where name == "ContentDecodingException"
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700701
702 this.readStartElement(startTag, attributes); // can't use getElementText, can't get attributes
703 //String
Jeff Thompson41ef0f92012-11-24 09:22:55 -0800704 var strElementText = this.readUString();
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700705 return strElementText;
706};
Jeff Thompson1b196592012-10-14 17:07:40 -0700707
Jeff Thompsonc92706b2012-11-11 19:12:58 -0800708
Jeff Thompson1b196592012-10-14 17:07:40 -0700709/*
710 * Set the offset into the input, used for the next read.
711 */
712BinaryXMLDecoder.prototype.seek = function(
713 //int
714 offset) {
Jeff Thompsonc92706b2012-11-11 19:12:58 -0800715 this.offset = offset;
Jeff Thompson1b196592012-10-14 17:07:40 -0700716}
Jeff Thompsoncab74c32012-10-21 13:27:28 -0700717
718/*
719 * Call with: throw new ContentDecodingException(new Error("message")).
720 */
721function ContentDecodingException(error) {
722 this.message = error.message;
723 // Copy lineNumber, etc. from where new Error was called.
724 for (var prop in error)
725 this[prop] = error[prop];
726}
727ContentDecodingException.prototype = new Error();
728ContentDecodingException.prototype.name = "ContentDecodingException";
729