6 if (typeof JSROOT !=
"object") {
7 var e1 =
new Error(
"This extension requires JSRootCore.js");
8 e1.source =
"JSRootIOEvolution.js";
12 if (typeof JSROOT.IO ==
"object") {
13 var e1 =
new Error(
"This JSROOT IO already loaded");
14 e1.source =
"JSRootIOEvolution.js";
19 kBase : 0, kOffsetL : 20, kOffsetP : 40, kCounter : 6, kCharStar : 7,
20 kChar : 1, kShort : 2, kInt : 3, kLong : 4, kFloat : 5,
21 kDouble : 8, kDouble32 : 9, kLegacyChar : 10, kUChar : 11, kUShort : 12,
22 kUInt : 13, kULong : 14, kBits : 15, kLong64 : 16, kULong64 : 17, kBool : 18,
24 kObject : 61, kAny : 62, kObjectp : 63, kObjectP : 64, kTString : 65,
25 kTObject : 66, kTNamed : 67, kAnyp : 68, kAnyP : 69, kAnyPnoVT : 70,
27 kSkip : 100, kSkipL : 120, kSkipP : 140,
28 kConv : 200, kConvL : 220, kConvP : 240,
29 kSTL : 300, kSTLstring : 365,
30 kStreamer : 500, kStreamLoop : 501,
32 kByteCountMask : 0x40000000,
33 kNewClassTag : 0xFFFFFFFF,
34 kClassMask : 0x80000000,
39 JSROOT.fUserStreamers = null;
41 JSROOT.addUserStreamer =
function(type, user_streamer)
43 if (JSROOT.fUserStreamers == null) JSROOT.fUserStreamers = {};
44 JSROOT.fUserStreamers[type] = user_streamer;
47 JSROOT.R__unzip_header =
function(str, off, noalert) {
50 if (off + JSROOT.IO.Z_HDRSIZE > str.length) {
51 if (!noalert) alert(
"Error R__unzip_header: header size exceeds buffer size");
56 if (!(str.charAt(off) ==
'Z' && str.charAt(off+1) ==
'L' && str.charCodeAt(off+2) == JSROOT.IO.Z_DEFLATED) &&
57 !(str.charAt(off) ==
'C' && str.charAt(off+1) ==
'S' && str.charCodeAt(off+2) == JSROOT.IO.Z_DEFLATED) &&
58 !(str.charAt(off) ==
'X' && str.charAt(off+1) ==
'Z' && str.charCodeAt(off+2) == 0)) {
59 if (!noalert) alert(
"Error R__unzip_header: error in header");
62 return JSROOT.IO.Z_HDRSIZE +
63 ((str.charCodeAt(off+3) & 0xff) |
64 ((str.charCodeAt(off+4) & 0xff) << 8) |
65 ((str.charCodeAt(off+5) & 0xff) << 16));
68 JSROOT.R__unzip =
function(srcsize, str, off, noalert) {
71 if (srcsize < JSROOT.IO.Z_HDRSIZE) {
72 if (!noalert) alert(
"R__unzip: too small source");
77 if (!(str.charAt(off) ==
'Z' && str.charAt(off+1) ==
'L' && str.charCodeAt(off+2) == JSROOT.IO.Z_DEFLATED) &&
78 !(str.charAt(off) ==
'C' && str.charAt(off+1) ==
'S' && str.charCodeAt(off+2) == JSROOT.IO.Z_DEFLATED) &&
79 !(str.charAt(off) ==
'X' && str.charAt(off+1) ==
'Z' && str.charCodeAt(off+2) == 0)) {
80 if (!noalert) alert(
"Error R__unzip: error in header");
83 var ibufcnt = ((str.charCodeAt(off+3) & 0xff) |
84 ((str.charCodeAt(off+4) & 0xff) << 8) |
85 ((str.charCodeAt(off+5) & 0xff) << 16));
86 if (ibufcnt + JSROOT.IO.Z_HDRSIZE != srcsize) {
87 if (!noalert) alert(
"R__unzip: discrepancy in source length");
92 if (str.charAt(off) ==
'Z' && str.charAt(off+1) ==
'L') {
94 var data = str.substr(off + JSROOT.IO.Z_HDRSIZE + 2, srcsize);
95 return RawInflate.inflate(data);
99 if (!noalert) alert(
"R__unzip: Old zlib format is not supported!");
106 JSROOT.ReconstructObject =
function(class_name, obj_rawdata, sinfo_rawdata) {
118 var file =
new JSROOT.TFile;
119 var buf =
new JSROOT.TBuffer(sinfo_rawdata, 0, file);
120 file.ExtractStreamerInfos(buf);
124 buf =
new JSROOT.TBuffer(obj_rawdata, 0, file);
125 buf.MapObject(obj, 1);
126 buf.ClassStreamer(obj, class_name);
131 JSROOT.TBuffer =
function(_str, _o, _file) {
132 this._typename =
"TBuffer";
134 this.o = (_o==null) ? 0 : _o;
136 this.ClearObjectMap();
141 JSROOT.TBuffer.prototype.locate =
function(pos) {
145 JSROOT.TBuffer.prototype.shift =
function(cnt) {
149 JSROOT.TBuffer.prototype.ntou1 =
function() {
150 return (this.b.charCodeAt(
this.o++) & 0xff) >>> 0;
153 JSROOT.TBuffer.prototype.ntou2 =
function() {
155 var n = ((this.b.charCodeAt(this.o) & 0xff) << 8) >>> 0;
156 n += (this.b.charCodeAt(this.o+1) & 0xff) >>> 0;
161 JSROOT.TBuffer.prototype.ntou4 =
function() {
163 var n = ((this.b.charCodeAt(this.o) & 0xff) << 24) >>> 0;
164 n += ((this.b.charCodeAt(this.o+1) & 0xff) << 16) >>> 0;
165 n += ((this.b.charCodeAt(this.o+2) & 0xff) << 8) >>> 0;
166 n += (this.b.charCodeAt(this.o+3) & 0xff) >>> 0;
171 JSROOT.TBuffer.prototype.ntou8 =
function() {
173 var n = ((this.b.charCodeAt(this.o) & 0xff) << 56) >>> 0;
174 n += ((this.b.charCodeAt(this.o+1) & 0xff) << 48) >>> 0;
175 n += ((this.b.charCodeAt(this.o+2) & 0xff) << 40) >>> 0;
176 n += ((this.b.charCodeAt(this.o+3) & 0xff) << 32) >>> 0;
177 n += ((this.b.charCodeAt(this.o+4) & 0xff) << 24) >>> 0;
178 n += ((this.b.charCodeAt(this.o+5) & 0xff) << 16) >>> 0;
179 n += ((this.b.charCodeAt(this.o+6) & 0xff) << 8) >>> 0;
180 n += (this.b.charCodeAt(this.o+7) & 0xff) >>> 0;
185 JSROOT.TBuffer.prototype.ntoi1 =
function() {
186 return (this.b.charCodeAt(
this.o++) & 0xff);
189 JSROOT.TBuffer.prototype.ntoi2 =
function() {
191 var n = (this.b.charCodeAt(this.o) & 0xff) << 8;
192 n += (this.b.charCodeAt(this.o+1) & 0xff);
197 JSROOT.TBuffer.prototype.ntoi4 =
function() {
199 var n = ((this.b.charCodeAt(this.o) & 0xff) << 24) +
200 ((this.b.charCodeAt(this.o+1) & 0xff) << 16) +
201 ((this.b.charCodeAt(this.o+2) & 0xff) << 8) +
202 ((this.b.charCodeAt(this.o+3) & 0xff));
207 JSROOT.TBuffer.prototype.ntoi8 =
function(b, o) {
209 var n = (this.b.charCodeAt(this.o) & 0xff) << 56;
210 n += (this.b.charCodeAt(this.o+1) & 0xff) << 48;
211 n += (this.b.charCodeAt(this.o+2) & 0xff) << 40;
212 n += (this.b.charCodeAt(this.o+3) & 0xff) << 32;
213 n += (this.b.charCodeAt(this.o+4) & 0xff) << 24;
214 n += (this.b.charCodeAt(this.o+5) & 0xff) << 16;
215 n += (this.b.charCodeAt(this.o+6) & 0xff) << 8;
216 n += (this.b.charCodeAt(this.o+7) & 0xff);
221 JSROOT.TBuffer.prototype.ntof =
function() {
223 var inString = this.b.substring(this.o, this.o + 4); this.o+=4;
224 if (inString.length < 4)
return Number.NaN;
226 for (var i=0; i<4; i++) {
227 var curByte = (inString.charCodeAt(i) & 0xff).toString(2);
228 var byteLen = curByte.length;
230 for (var bit=0; bit<(8-byteLen); bit++)
231 curByte =
'0' + curByte;
233 bits = bits + curByte;
236 var bsign = (bits.charAt(0) ==
'1') ? -1 : 1;
237 var bexp = parseInt(bits.substring(1, 9), 2) - 127;
243 for (var i=0; i<23; i++) {
244 if (parseInt(bits.substr(9+i, 1)) == 1)
245 bman = bman + 1 / Math.pow(2, i+1);
248 return (bsign * Math.pow(2, bexp) * bman);
251 JSROOT.TBuffer.prototype.ntod =
function() {
253 var inString = this.b.substring(this.o, this.o + 8); this.o+=8;
254 if (inString.length < 8)
return Number.NaN;
256 for (var i=0; i<8; i++) {
257 var curByte = (inString.charCodeAt(i) & 0xff).toString(2);
258 var byteLen = curByte.length;
260 for (var bit=0; bit<(8-byteLen); bit++)
261 curByte =
'0' + curByte;
263 bits = bits + curByte;
266 var bsign = (bits.charAt(0) ==
'1') ? -1 : 1;
267 var bexp = parseInt(bits.substring(1, 12), 2) - 1023;
273 for (var i=0; i<52; i++) {
274 if (parseInt(bits.substr(12+i, 1)) == 1)
275 bman = bman + 1 / Math.pow(2, i+1);
278 return (bsign * Math.pow(2, bexp) * bman);
282 JSROOT.TBuffer.prototype.ReadFastArray =
function(n, array_type) {
284 var array =
new Array();
285 switch (array_type) {
287 for (var i = 0; i < n; ++i) {
288 array[i] = this.ntod();
289 if (Math.abs(array[i]) < 1e-300) array[i] = 0.0;
293 for (var i = 0; i < n; ++i) {
294 array[i] = this.ntof();
295 if (Math.abs(array[i]) < 1e-300) array[i] = 0.0;
299 for (var i = 0; i < n; ++i)
300 array[i] = this.ntoi8();
303 for (var i = 0; i < n; ++i)
304 array[i] = this.ntou8();
307 for (var i = 0; i < n; ++i)
308 array[i] = this.ntoi4();
311 for (var i = 0; i < n; ++i)
312 array[i] = this.ntou4();
315 for (var i = 0; i < n; ++i)
316 array[i] = this.ntoi2();
319 for (var i = 0; i < n; ++i)
320 array[i] = this.b.charCodeAt(
this.o++) & 0xff;
323 for (var i = 0; i < n; ++i)
324 array[i] = this.ReadTString();
327 for (var i = 0; i < n; ++i)
328 array[i] = this.ntou4();
335 JSROOT.TBuffer.prototype.ReadBasicPointer =
function(len, array_type) {
336 var isArray = this.b.charCodeAt(this.o++) & 0xff;
338 return this.ReadFastArray(len, array_type);
340 if (len==0)
return new Array();
343 return this.ReadFastArray(len, array_type);
347 JSROOT.TBuffer.prototype.ReadString =
function(max_len) {
349 max_len = typeof(max_len) !=
'undefined' ? max_len : 0;
352 while ((max_len==0) || (len<max_len)) {
353 if ((this.b.charCodeAt(
this.o++) & 0xff) == 0)
break;
357 return (len == 0) ?
"" : this.b.substring(pos0, pos0 + len);
360 JSROOT.TBuffer.prototype.ReadTString =
function() {
362 var len = this.b.charCodeAt(this.o++) & 0xff;
364 if (len == 255) len = this.ntou4();
369 return (this.b.charCodeAt(pos) == 0) ?
'' : this.b.substring(pos, pos + len);
373 JSROOT.TBuffer.prototype.GetMappedObject =
function(tag) {
374 return this.fObjectMap[tag];
377 JSROOT.TBuffer.prototype.MapObject =
function(tag, obj) {
378 if (obj==null)
return;
379 this.fObjectMap[tag] = obj;
382 JSROOT.TBuffer.prototype.MapClass =
function(tag, classname) {
383 this.fClassMap[tag] = classname;
386 JSROOT.TBuffer.prototype.GetMappedClass =
function(tag) {
387 if (tag in this.fClassMap)
return this.fClassMap[tag];
391 JSROOT.TBuffer.prototype.ClearObjectMap =
function() {
392 this.fObjectMap = {};
394 this.fObjectMap[0] = null;
397 JSROOT.TBuffer.prototype.ReadVersion =
function() {
400 var bytecnt = this.ntou4();
401 if (bytecnt & JSROOT.IO.kByteCountMask)
402 ver[
'bytecnt'] = bytecnt - JSROOT.IO.kByteCountMask - 2;
403 ver[
'val'] = this.ntou2();
408 JSROOT.TBuffer.prototype.CheckBytecount =
function(ver, where) {
409 if ((
'bytecnt' in ver) && (ver[
'off'] + ver[
'bytecnt'] != this.o)) {
411 alert(
"Missmatch in " + where +
" bytecount expected = " + ver[
'bytecnt'] +
" got = " + (this.o-ver[
'off']));
412 this.o = ver[
'off'] + ver[
'bytecnt'];
418 JSROOT.TBuffer.prototype.ReadTObject =
function(tobj) {
420 if ((!
'_typename' in tobj) || (tobj[
'_typename'] ==
''))
421 tobj[
'_typename'] =
"TObject";
423 tobj[
'fUniqueID'] = this.ntou4();
424 tobj[
'fBits'] = this.ntou4();
428 JSROOT.TBuffer.prototype.ReadTNamed =
function(tobj) {
430 var ver = this.ReadVersion();
431 this.ReadTObject(tobj);
432 tobj[
'fName'] = this.ReadTString();
433 tobj[
'fTitle'] = this.ReadTString();
434 return this.CheckBytecount(ver,
"ReadTNamed");
437 JSROOT.TBuffer.prototype.ReadTObjString =
function(tobj) {
439 var ver = this.ReadVersion();
440 this.ReadTObject(tobj);
441 tobj[
'fString'] = this.ReadTString();
442 return this.CheckBytecount(ver,
"ReadTObjString");
445 JSROOT.TBuffer.prototype.ReadTList =
function(list) {
447 list[
'_typename'] =
"TList";
449 list[
'arr'] =
new Array;
450 list[
'opt'] =
new Array;
451 var ver = this.ReadVersion();
452 if (ver[
'val'] > 3) {
453 this.ReadTObject(list);
454 list[
'name'] = this.ReadTString();
455 var nobjects = this.ntou4();
456 for (var i = 0; i < nobjects; ++i) {
458 var obj = this.ReadObjectAny();
459 list[
'arr'].push(obj);
461 var opt = this.ReadTString();
462 list[
'opt'].push(opt);
466 return this.CheckBytecount(ver);
469 JSROOT.TBuffer.prototype.ReadTObjArray =
function(list) {
470 list[
'_typename'] =
"TObjArray";
472 list[
'arr'] =
new Array();
473 var ver = this.ReadVersion();
475 this.ReadTObject(list);
477 list[
'name'] = this.ReadTString();
478 var nobjects = this.ntou4();
479 var lowerbound = this.ntou4();
480 for (var i = 0; i < nobjects; i++) {
481 var obj = this.ReadObjectAny();
482 list[
'arr'].push(obj);
484 return this.CheckBytecount(ver,
"ReadTObjArray");
487 JSROOT.TBuffer.prototype.ReadTClonesArray =
function(list) {
488 list[
'_typename'] =
"TClonesArray";
490 list[
'arr'] =
new Array();
491 var ver = this.ReadVersion();
493 this.ReadTObject(list);
495 list[
'name'] = this.ReadTString();
496 var s = this.ReadTString();
499 var pos = s.indexOf(
";");
501 classv = s.slice(0, pos);
502 s = s.slice(pos+1, s.length()-pos-1);
505 var nobjects = this.ntou4();
506 if (nobjects < 0) nobjects = -nobjects;
507 var lowerbound = this.ntou4();
508 for (var i = 0; i < nobjects; i++) {
511 this.ClassStreamer(obj, classv);
513 list[
'arr'].push(obj);
515 return this.CheckBytecount(ver,
"ReadTClonesArray");
518 JSROOT.TBuffer.prototype.ReadTPolyMarker3D =
function(marker) {
519 var ver = this.ReadVersion();
521 this.ReadTObject(marker);
523 this.ClassStreamer(marker,
"TAttMarker");
525 marker[
'fN'] = this.ntoi4();
527 marker[
'fP'] = this.ReadFastArray(marker[
'fN']*3,
'F');
529 marker[
'fOption'] = this.ReadTString();
532 marker[
'fName'] = this.ReadTString();
534 marker[
'fName'] =
"TPolyMarker3D";
536 return this.CheckBytecount(ver,
"ReadTPolyMarker3D");
539 JSROOT.TBuffer.prototype.ReadTCollection =
function(list, str, o) {
540 list[
'_typename'] =
"TCollection";
542 list[
'arr'] =
new Array();
543 var ver = this.ReadVersion();
545 this.ReadTObject(list);
547 list[
'name'] = this.ReadTString();
548 var nobjects = this.ntou4();
549 for (var i = 0; i < nobjects; i++) {
551 list[
'arr'].push(null);
553 return this.CheckBytecount(ver,
"ReadTCollection");
556 JSROOT.TBuffer.prototype.ReadTCanvas =
function(obj) {
558 var ver = this.ReadVersion();
560 this.ClassStreamer(obj,
"TPad");
562 obj[
'fDISPLAY'] = this.ReadTString();
563 obj[
'fDoubleBuffer'] = this.ntoi4();
564 obj[
'fRetained'] = this.ntou1()!=0;
565 obj[
'fXsizeUser'] = this.ntoi4();
566 obj[
'fYsizeUser'] = this.ntoi4();
567 obj[
'fXsizeReal'] = this.ntoi4();
568 obj[
'fYsizeReal'] = this.ntoi4();
569 obj[
'fWindowTopX'] = this.ntoi4();
570 obj[
'fWindowTopY'] = this.ntoi4();
571 obj[
'fWindowWidth'] = this.ntoi4();
572 obj[
'fWindowHeight'] = this.ntoi4();
573 obj[
'fCw'] = this.ntou4();
574 obj[
'fCh'] = this.ntou4();
577 this.ClassStreamer(obj[
'fCatt'],
"TAttCanvas");
580 obj[
'fHighLightColor'] = this.ntoi2();
581 obj[
'fBatch'] = this.ntou1()!=0;
587 return this.CheckBytecount(ver,
"TCanvas");
591 JSROOT.TBuffer.prototype.ReadTStreamerInfo =
function(streamerinfo) {
594 var R__v = this.ReadVersion();
595 if (R__v[
'val'] > 1) {
596 this.ReadTNamed(streamerinfo);
598 streamerinfo[
'fCheckSum'] = this.ntou4();
599 streamerinfo[
'fClassVersion'] = this.ntou4();
601 streamerinfo[
'fElements'] = this.ReadObjectAny();
603 return this.CheckBytecount(R__v,
"ReadTStreamerInfo");
606 JSROOT.TBuffer.prototype.ReadStreamerElement =
function(element) {
609 var R__v = this.ReadVersion();
610 this.ReadTNamed(element);
611 element[
'type'] = this.ntou4();
612 element[
'size'] = this.ntou4();
613 element[
'length'] = this.ntou4();
614 element[
'dim'] = this.ntou4();
615 if (R__v[
'val'] == 1) {
616 var n = this.ntou4();
617 element[
'maxindex'] = this.ReadFastArray(n,
'U');
619 element[
'maxindex'] = this.ReadFastArray(5,
'U');
621 element[
'fTypeName'] = this.ReadTString();
622 element[
'typename'] = element[
'fTypeName'];
623 if ((element[
'type'] == 11) && (element[
'typename'] ==
"Bool_t" ||
624 element[
'typename'] ==
"bool"))
625 element[
'type'] = 18;
626 if (R__v[
'val'] > 1) {
629 if (R__v[
'val'] <= 2) {
634 if (R__v[
'val'] == 3) {
635 element[
'xmin'] = this.ntou4();
636 element[
'xmax'] = this.ntou4();
637 element[
'factor'] = this.ntou4();
640 if (R__v[
'val'] > 3) {
643 return this.CheckBytecount(R__v,
"ReadStreamerElement");
647 JSROOT.TBuffer.prototype.ReadStreamerBase =
function(streamerbase) {
650 var R__v = this.ReadVersion();
651 this.ReadStreamerElement(streamerbase);
652 if (R__v[
'val'] > 2) {
653 streamerbase[
'baseversion'] = this.ntou4();
655 return this.CheckBytecount(R__v,
"ReadStreamerBase");
658 JSROOT.TBuffer.prototype.ReadStreamerBasicType =
function(streamerbase) {
660 var R__v = this.ReadVersion();
661 if (R__v[
'val'] > 1) {
662 this.ReadStreamerElement(streamerbase);
664 return this.CheckBytecount(R__v,
"ReadStreamerBasicType");
667 JSROOT.TBuffer.prototype.ReadStreamerBasicPointer =
function(streamerbase) {
669 var R__v = this.ReadVersion();
670 if (R__v[
'val'] > 1) {
671 this.ReadStreamerElement(streamerbase);
672 streamerbase[
'countversion'] = this.ntou4();
673 streamerbase[
'countName'] = this.ReadTString();
674 streamerbase[
'countClass'] = this.ReadTString();
676 return this.CheckBytecount(R__v,
"ReadStreamerBasicPointer");
679 JSROOT.TBuffer.prototype.ReadStreamerSTL =
function(streamerSTL) {
682 var R__v = this.ReadVersion();
683 if (R__v[
'val'] > 2) {
684 this.ReadStreamerElement(streamerSTL);
685 streamerSTL[
'stltype'] = this.ntou4();
686 streamerSTL[
'ctype'] = this.ntou4();
688 return this.CheckBytecount(R__v,
"ReadStreamerSTL");
691 JSROOT.TBuffer.prototype.ReadTStreamerObject =
function(streamerbase) {
693 var R__v = this.ReadVersion();
694 if (R__v[
'val'] > 1) {
695 this.ReadStreamerElement(streamerbase);
697 return this.CheckBytecount(R__v,
"ReadTStreamerObject");
701 JSROOT.TBuffer.prototype.ReadClass =
function() {
704 classInfo[
'name'] = -1;
706 var bcnt = this.ntou4();
708 var startpos = this.o;
709 if (!(bcnt & JSROOT.IO.kByteCountMask) || (bcnt == JSROOT.IO.kNewClassTag)) {
716 if (!(tag & JSROOT.IO.kClassMask)) {
717 classInfo[
'objtag'] = tag;
720 if (tag == JSROOT.IO.kNewClassTag) {
722 classInfo[
'name'] = this.ReadString();
724 if (this.GetMappedClass(this.fTagOffset + startpos + JSROOT.IO.kMapOffset)==-1)
725 this.MapClass(this.fTagOffset + startpos + JSROOT.IO.kMapOffset, classInfo[
'name']);
729 var clTag = (tag & ~JSROOT.IO.kClassMask);
730 classInfo[
'name'] = this.GetMappedClass(clTag);
732 if (classInfo[
'name']==-1) {
733 alert(
"Did not found class with tag " + clTag);
742 JSROOT.TBuffer.prototype.ReadObjectAny =
function() {
743 var startpos = this.o;
744 var clRef = this.ReadClass();
747 if (
'objtag' in clRef)
748 return this.GetMappedObject(clRef[
'objtag']);
750 if (clRef[
'name'] == -1)
return null;
754 this.MapObject(this.fTagOffset + startpos + JSROOT.IO.kMapOffset, obj);
756 this.ClassStreamer(obj, clRef[
'name']);
761 JSROOT.TBuffer.prototype.ClassStreamer =
function(obj, classname) {
764 if (! (
'_typename' in obj)) obj[
'_typename'] = classname;
766 if (classname ==
'TObject' || classname ==
'TMethodCall') {
767 this.ReadTObject(obj);
769 else if (classname ==
'TQObject') {
772 else if (classname ==
'TObjString') {
773 this.ReadTObjString(obj);
775 else if (classname ==
'TObjArray') {
776 this.ReadTObjArray(obj);
778 else if (classname ==
'TClonesArray') {
779 this.ReadTClonesArray(obj);
781 else if ((classname ==
'TList') || (classname ==
'THashList')) {
784 else if (classname ==
'TCollection') {
785 this.ReadTCollection(obj);
786 alert(
"Trying to read TCollection - wrong!!!");
788 else if (classname ==
'TCanvas') {
789 this.ReadTCanvas(obj);
791 else if (classname ==
'TPolyMarker3D') {
792 this.ReadTPolyMarker3D(obj);
794 else if (classname ==
"TStreamerInfo") {
795 this.ReadTStreamerInfo(obj);
797 else if (classname ==
"TStreamerBase") {
798 this.ReadStreamerBase(obj);
800 else if (classname ==
"TStreamerBasicType") {
801 this.ReadStreamerBasicType(obj);
803 else if ((classname ==
"TStreamerBasicPointer") || (classname ==
"TStreamerLoop")) {
804 this.ReadStreamerBasicPointer(obj);
805 }
else if (classname ==
"TStreamerSTL") {
806 this.ReadStreamerSTL(obj);
807 }
else if (classname ==
"TStreamerObject" ||
808 classname ==
"TStreamerObjectAny" ||
809 classname ==
"TStreamerString" ||
810 classname ==
"TStreamerObjectPointer" ) {
811 this.ReadTStreamerObject(obj);
814 var streamer = this.fFile.GetStreamer(classname);
815 if (streamer != null)
816 streamer.Stream(obj,
this);
818 console.log(
"Did not found streamer for class " + classname +
" try to skip data");
819 var ver = this.ReadVersion();
820 this.CheckBytecount(ver);
824 JSROOT.addMethods(obj);
831 JSROOT.TStreamer =
function(file) {
833 this._typename =
"TStreamer";
838 JSROOT.TStreamer.prototype.ReadBasicType =
function(buf, obj, prop) {
841 switch (
this[prop][
'type']) {
842 case JSROOT.IO.kBase:
844 case JSROOT.IO.kOffsetL:
846 case JSROOT.IO.kOffsetP:
848 case JSROOT.IO.kCharStar:
849 var n_el = obj[
this[prop][
'cntname']];
850 obj[prop] = buf.ReadBasicPointer(n_el,
'C');
852 case JSROOT.IO.kChar:
853 case JSROOT.IO.kLegacyChar:
854 obj[prop] = buf.b.charCodeAt(buf.o++) & 0xff;
856 case JSROOT.IO.kShort:
857 obj[prop] = buf.ntoi2();
860 case JSROOT.IO.kCounter:
861 obj[prop] = buf.ntoi4();
863 case JSROOT.IO.kLong:
864 obj[prop] = buf.ntoi8();
866 case JSROOT.IO.kFloat:
867 case JSROOT.IO.kDouble32:
868 obj[prop] = buf.ntof();
869 if (Math.abs(obj[prop]) < 1e-300) obj[prop] = 0.0;
871 case JSROOT.IO.kDouble:
872 obj[prop] = buf.ntod();
873 if (Math.abs(obj[prop]) < 1e-300) obj[prop] = 0.0;
875 case JSROOT.IO.kUChar:
876 obj[prop] = (buf.b.charCodeAt(buf.o++) & 0xff) >>> 0;
878 case JSROOT.IO.kUShort:
879 obj[prop] = buf.ntou2();
881 case JSROOT.IO.kUInt:
882 obj[prop] = buf.ntou4();
884 case JSROOT.IO.kULong:
885 obj[prop] = buf.ntou8();
887 case JSROOT.IO.kBits:
888 alert(
'failed to stream ' + prop +
' (' +
this[prop][
'typename'] +
')');
890 case JSROOT.IO.kLong64:
891 obj[prop] = buf.ntoi8();
893 case JSROOT.IO.kULong64:
894 obj[prop] = buf.ntou8();
896 case JSROOT.IO.kBool:
897 obj[prop] = (buf.b.charCodeAt(buf.o++) & 0xff) != 0;
899 case JSROOT.IO.kFloat16:
904 case JSROOT.IO.kAnyp:
905 case JSROOT.IO.kObjectp:
906 case JSROOT.IO.kObject:
907 var classname =
this[prop][
'typename'];
908 if (classname.charAt(classname.length-1) ==
"*")
909 classname = classname.substr(0, classname.length - 1);
912 buf.ClassStreamer(obj[prop], classname);
915 case JSROOT.IO.kAnyP:
916 case JSROOT.IO.kObjectP:
917 obj[prop] = buf.ReadObjectAny();
919 case JSROOT.IO.kTString:
920 obj[prop] = buf.ReadTString();
922 case JSROOT.IO.kTObject:
923 buf.ReadTObject(obj);
925 case JSROOT.IO.kTNamed:
928 case JSROOT.IO.kAnyPnoVT:
929 case JSROOT.IO.kSTLp:
930 case JSROOT.IO.kSkip:
931 case JSROOT.IO.kSkipL:
932 case JSROOT.IO.kSkipP:
933 case JSROOT.IO.kConv:
934 case JSROOT.IO.kConvL:
935 case JSROOT.IO.kConvP:
937 case JSROOT.IO.kSTLstring:
938 case JSROOT.IO.kStreamer:
939 case JSROOT.IO.kStreamLoop:
940 alert(
'failed to stream ' + prop +
' (' +
this[prop][
'typename'] +
')');
942 case JSROOT.IO.kOffsetL+JSROOT.IO.kShort:
943 case JSROOT.IO.kOffsetL+JSROOT.IO.kUShort:
944 alert(
"Strange code was here????");
945 var n_el =
this[prop][
'length'];
946 obj[prop] = buf.ReadFastArray(n_el,
'S');
948 case JSROOT.IO.kOffsetL+JSROOT.IO.kInt:
949 var n_el =
this[prop][
'length'];
950 obj[prop] = buf.ReadFastArray(n_el,
'I');
952 case JSROOT.IO.kOffsetL+JSROOT.IO.kUInt:
953 var n_el =
this[prop][
'length'];
954 obj[prop] = buf.ReadFastArray(n_el,
'U');
956 case JSROOT.IO.kOffsetL+JSROOT.IO.kULong:
957 case JSROOT.IO.kOffsetL+JSROOT.IO.kULong64:
958 var n_el =
this[prop][
'length'];
959 obj[prop] = buf.ReadFastArray(n_el,
'LU');
961 case JSROOT.IO.kOffsetL+JSROOT.IO.kLong:
962 case JSROOT.IO.kOffsetL+JSROOT.IO.kLong64:
963 var n_el =
this[prop][
'length'];
964 obj[prop] = buf.ReadFastArray(n_el,
'L');
966 case JSROOT.IO.kOffsetL+JSROOT.IO.kFloat:
967 case JSROOT.IO.kOffsetL+JSROOT.IO.kDouble32:
969 var n_el =
this[prop][
'length'];
970 obj[prop] = buf.ReadFastArray(n_el,
'F');
972 case JSROOT.IO.kOffsetL+JSROOT.IO.kDouble:
974 var n_el =
this[prop][
'length'];
975 obj[prop] = buf.ReadFastArray(n_el,
'D');
977 case JSROOT.IO.kOffsetP+JSROOT.IO.kChar:
978 var n_el = obj[
this[prop][
'cntname']];
979 obj[prop] = buf.ReadBasicPointer(n_el,
'C');
981 case JSROOT.IO.kOffsetP+JSROOT.IO.kShort:
982 case JSROOT.IO.kOffsetP+JSROOT.IO.kUShort:
983 var n_el = obj[
this[prop][
'cntname']];
984 obj[prop] = buf.ReadBasicPointer(n_el,
'S');
986 case JSROOT.IO.kOffsetP+JSROOT.IO.kInt:
987 var n_el = obj[
this[prop][
'cntname']];
988 obj[prop] = buf.ReadBasicPointer(n_el,
'I');
990 case JSROOT.IO.kOffsetP+JSROOT.IO.kUInt:
991 var n_el = obj[
this[prop][
'cntname']];
992 obj[prop] = buf.ReadBasicPointer(n_el,
'U');
994 case JSROOT.IO.kOffsetP+JSROOT.IO.kULong:
995 case JSROOT.IO.kOffsetP+JSROOT.IO.kULong64:
996 var n_el = obj[
this[prop][
'cntname']];
997 obj[prop] = buf.ReadBasicPointer(n_el,
'LU');
999 case JSROOT.IO.kOffsetP+JSROOT.IO.kLong:
1000 case JSROOT.IO.kOffsetP+JSROOT.IO.kLong64:
1001 var n_el = obj[
this[prop][
'cntname']];
1002 obj[prop] = buf.ReadBasicPointer(n_el,
'L');
1004 case JSROOT.IO.kOffsetP+JSROOT.IO.kFloat:
1005 case JSROOT.IO.kOffsetP+JSROOT.IO.kDouble32:
1006 var n_el = obj[
this[prop][
'cntname']];
1007 obj[prop] = buf.ReadBasicPointer(n_el,
'F');
1009 case JSROOT.IO.kOffsetP+JSROOT.IO.kDouble:
1010 var n_el = obj[
this[prop][
'cntname']];
1011 obj[prop] = buf.ReadBasicPointer(n_el,
'D');
1014 alert(
'failed to stream ' + prop +
' (' +
this[prop][
'typename'] +
')');
1019 JSROOT.TStreamer.prototype.Stream =
function(obj, buf) {
1021 var ver = buf.ReadVersion();
1024 for (var prop in
this) {
1025 if (!
this[prop] || typeof(
this[prop]) ===
"function")
1027 if (
this[prop][
'typename'] ===
'BASE') {
1028 var clname =
this[prop][
'class'];
1029 if (
this[prop][
'class'].indexOf(
"TArray") == 0) {
1030 var array_type =
this[prop][
'class'].charAt(6);
1031 obj[
'fN'] = buf.ntou4();
1032 obj[
'fArray'] = buf.ReadFastArray(obj[
'fN'], array_type);
1034 buf.ClassStreamer(obj,
this[prop][
'class']);
1039 for (var prop in
this) {
1041 if (!
this[prop] || typeof(
this[prop]) ===
"function")
continue;
1043 var prop_typename =
this[prop][
'typename'];
1045 if (typeof(prop_typename) ===
"undefined" || prop_typename ===
"BASE")
continue;
1047 if (JSROOT.fUserStreamers !== null) {
1048 var user_func = JSROOT.fUserStreamers[prop_typename];
1050 if (user_func !== undefined) {
1051 user_func(buf, obj, prop,
this);
1057 switch (prop_typename) {
1060 var r__v = buf.ReadVersion();
1061 obj[prop] =
new Array();
1062 for (var i = 0; i<obj[
this[prop][
'cntname']]; ++i )
1063 obj[prop][i] = buf.ReadTString();
1064 buf.CheckBytecount(r__v,
"TString* array");
1073 var array_type =
this[prop][
'typename'].charAt(6);
1074 var n = buf.ntou4();
1075 obj[prop] = buf.ReadFastArray(n, array_type);
1079 buf.ReadTObject(obj);
1087 this.ReadBasicType(buf, obj, prop);
1091 if ((
'fBits' in obj) && !(
'TestBit' in obj)) {
1092 obj[
'TestBit'] =
function (f) {
1093 return ((obj[
'fBits'] & f) != 0);
1097 buf.CheckBytecount(ver,
"TStreamer.Stream");
1110 JSROOT.TDirectory =
function(file, dirname, cycle) {
1111 if (! (
this instanceof arguments.callee) ) {
1112 var error =
new Error(
"you must use new to instantiate this class");
1113 error.source =
"JSROOT.TDirectory.ctor";
1118 this._typename =
"TDirectory";
1119 this[
'dir_name'] = dirname;
1120 this[
'dir_cycle'] = cycle;
1121 this.fKeys =
new Array();
1126 JSROOT.TDirectory.prototype.GetKey =
function(keyname, cycle, call_back) {
1128 for (var i in this.fKeys) {
1129 if (this.fKeys[i][
'fName'] == keyname && this.fKeys[i][
'fCycle'] == cycle) {
1130 if (typeof call_back ==
'function') call_back(this.fKeys[i]);
1131 return this.fKeys[i];
1135 var pos = keyname.lastIndexOf(
"/");
1138 var dirname = keyname.substr(0, pos);
1139 var subname = keyname.substr(pos+1);
1141 var dirkey = this.GetKey(dirname, 1);
1142 if ((dirkey!=null) && (typeof call_back ==
'function') &&
1143 (dirkey[
'fClassName'].indexOf(
"TDirectory")==0)) {
1145 this.fFile.ReadObject(
this[
'dir_name'] +
"/" + dirname, 1,
function(newdir) {
1146 if (newdir) newdir.GetKey(subname, cycle, call_back);
1151 pos = keyname.lastIndexOf(
"/", pos-1);
1154 if (typeof call_back ==
'function') call_back(null);
1158 JSROOT.TDirectory.prototype.ReadKeys =
function(readkeys_callback) {
1160 if (typeof readkeys_callback !=
'function')
1161 readkeys_callback =
function() {};
1164 var file = this.fFile;
1167 var nbytes = this.fNbytesName + 22;
1172 if (file.fVersion >= 40000) nbytes += 12;
1174 file.Seek(this.fSeekDir, this.fFile.ERelativeTo.kBeg);
1175 file.ReadBuffer(nbytes,
function(blob1) {
1176 if (blob1==null)
return readkeys_callback(null);
1177 var buf =
new JSROOT.TBuffer(blob1, thisdir.fNbytesName, file);
1179 thisdir.StreamHeader(buf);
1183 var keyversion = buf.ntoi2();
1185 if (keyversion > 1000) buf.shift(28);
1189 thisdir.fTitle = buf.ReadTString();
1190 if (thisdir.fNbytesName < 10 || thisdir.fNbytesName > 10000) {
1191 console.log(
"Cannot read directory info of file " + file.fURL);
1192 return readkeys_callback(null);
1196 if (thisdir.fSeekKeys <=0)
1197 return readkeys_callback(null);
1199 file.Seek(thisdir.fSeekKeys, file.ERelativeTo.kBeg);
1200 file.ReadBuffer(thisdir.fNbytesKeys,
function(blob2) {
1201 if (blob2 == null) readkeys_callback(null);
1203 var buf =
new JSROOT.TBuffer(blob2, 0, file);
1205 var key = file.ReadKey(buf);
1207 var nkeys = buf.ntoi4();
1208 for (var i = 0; i < nkeys; i++) {
1209 key = file.ReadKey(buf);
1210 thisdir.fKeys.push(key);
1212 file.fDirectories.push(thisdir);
1215 readkeys_callback(thisdir);
1222 JSROOT.TDirectory.prototype.StreamHeader =
function(buf) {
1223 var version = buf.ntou2();
1224 var versiondir = version%1000;
1226 this.fNbytesKeys = buf.ntou4();
1227 this.fNbytesName = buf.ntou4();
1228 this.fSeekDir = (version > 1000) ? buf.ntou8() : buf.ntou4();
1229 this.fSeekParent = (version > 1000) ? buf.ntou8() : buf.ntou4();
1230 this.fSeekKeys = (version > 1000) ? buf.ntou8() : buf.ntou4();
1231 if (versiondir > 2) buf.shift(18);
1262 JSROOT.TFile =
function(url, newfile_callback) {
1263 if (! (
this instanceof arguments.callee) ) {
1264 var error =
new Error(
"you must use new to instantiate this class");
1265 error.source =
"JSROOT.TFile.ctor";
1269 this._typename =
"TFile";
1273 this.fAcceptRanges =
true;
1274 this.fFullFileContent =
"";
1276 this.ERelativeTo = { kBeg : 0, kCur : 1, kEnd : 2 };
1277 this.fDirectories =
new Array();
1278 this.fKeys =
new Array();
1280 this.fNbytesInfo = 0;
1281 this.fTagOffset = 0;
1282 this.fStreamers = 0;
1283 this.fStreamerInfos = null;
1284 this.fFileName =
"";
1285 this.fStreamers =
new Array;
1287 if (typeof this.fURL !=
'string')
return this;
1289 if (this.fURL.charAt(
this.fURL.length-1) ==
"+") {
1290 this.fURL = this.fURL.substr(0, this.fURL.length-1);
1291 this.fAcceptRanges =
false;
1294 var pos = Math.max(this.fURL.lastIndexOf(
"/"), this.fURL.lastIndexOf(
"\\"));
1295 this.fFileName = pos>=0 ? this.fURL.substr(pos+1) : this.fURL;
1297 if (!this.fAcceptRanges) {
1298 this.ReadKeys(newfile_callback);
1302 var xhr = JSROOT.NewHttpRequest(this.fURL,
"head",
function(res) {
1304 if (typeof newfile_callback ==
'function')
1305 newfile_callback(null);
1309 var accept_ranges = res.getResponseHeader(
"Accept-Ranges");
1310 if (accept_ranges==null) file.fAcceptRanges =
false;
1311 var len = res.getResponseHeader(
"Content-Length");
1312 if (len!=null) file.fEND = parseInt(len);
1313 else file.fAcceptRanges =
false;
1314 file.ReadKeys(newfile_callback);
1323 JSROOT.TFile.prototype.ReadBuffer =
function(len, callback) {
1325 if (!this.fAcceptRanges && (this.fFullFileContent.length>0))
1326 return callback(this.fFullFileContent.substr(
this.fOffset, len));
1330 var url = this.fURL;
1331 if (this.fAcceptRanges) {
1333 if (url.indexOf(
'?')>0) url+=
"&stamp=";
else url +=
"?stamp=";
1338 var xhr = JSROOT.NewHttpRequest(url,
"bin",
function(res) {
1339 if ((res!=null) && !file.fAcceptRanges && (file.fFullFileContent.length == 0)) {
1341 file.fFullFileContent = res;
1342 file.fEND = res.length;
1343 res = file.fFullFileContent.substr(file.fOffset, len);
1349 if (this.fAcceptRanges)
1350 xhr.setRequestHeader(
"Range",
"bytes=" + this.fOffset +
"-" + (this.fOffset + len - 1));
1356 JSROOT.TFile.prototype.Seek =
function(offset, pos) {
1359 case this.ERelativeTo.kBeg:
1360 this.fOffset = offset;
1362 case this.ERelativeTo.kCur:
1363 this.fOffset += offset;
1365 case this.ERelativeTo.kEnd:
1368 throw "Seek : seeking from end in file with fEND==0 is not supported";
1369 this.fOffset = this.fEND - offset;
1372 throw "Seek : unknown seek option (" + pos +
")";
1377 JSROOT.TFile.prototype.ReadHeader =
function(str) {
1379 if (str.substring(0, 4) !=
"root") {
1385 var buf =
new JSROOT.TBuffer(str, 4,
this);
1386 header[
'version'] = buf.ntou4();
1387 header[
'begin'] = buf.ntou4();
1388 var largeFile = header[
'version'] >= 1000000;
1389 header[
'end'] = largeFile ? buf.ntou8() : buf.ntou4();
1390 header[
'seekFree'] = largeFile ? buf.ntou8() : buf.ntou4();
1392 header[
'units'] = buf.ntoi1();
1393 header[
'fCompress'] = buf.ntou4();
1394 header[
'seekInfo'] = largeFile ? buf.ntou8() : buf.ntou4();
1395 header[
'nbytesInfo'] = buf.ntou4();
1397 if (!header[
'seekInfo'] && !header[
'nbytesInfo']) {
1401 this.fSeekInfo = header[
'seekInfo'];
1402 this.fNbytesInfo = header[
'nbytesInfo'];
1406 JSROOT.TFile.prototype.ReadKey =
function(buf) {
1410 key[
'fNbytes'] = buf.ntoi4();
1411 key[
'fVersion'] = buf.ntoi2();
1412 key[
'fObjlen'] = buf.ntou4();
1413 var datime = buf.ntou4();
1414 key[
'fDatime'] =
new Date();
1415 key[
'fDatime'].setFullYear((datime >>> 26) + 1995);
1416 key[
'fDatime'].setMonth((datime << 6) >>> 28);
1417 key[
'fDatime'].setDate((datime << 10) >>> 27);
1418 key[
'fDatime'].setHours((datime << 15) >>> 27);
1419 key[
'fDatime'].setMinutes((datime << 20) >>> 26);
1420 key[
'fDatime'].setSeconds((datime << 26) >>> 26);
1421 key[
'fDatime'].setMilliseconds(0);
1422 key[
'fKeylen'] = buf.ntou2();
1423 key[
'fCycle'] = buf.ntou2();
1424 if (key[
'fVersion'] > 1000) {
1425 key[
'fSeekKey'] = buf.ntou8();
1428 key[
'fSeekKey'] = buf.ntou4();
1431 key[
'fClassName'] = buf.ReadTString();
1432 key[
'fName'] = buf.ReadTString();
1433 key[
'fTitle'] = buf.ReadTString();
1435 var name = key[
'fName'].replace(/[
'"]/g,'');
1437 if (name != key['fName
']) {
1438 key['fRealName
'] = key['fName
'];
1439 key['fName
'] = name;
1445 JSROOT.TFile.prototype.GetDir = function(dirname, cycle) {
1446 // check first that directory with such name exists
1447 for (var j in this.fDirectories) {
1448 var dir = this.fDirectories[j];
1449 if (dir['dir_name
'] != dirname) continue;
1450 if ((cycle!=null) && (dir['dir_cycle
']!=cycle)) continue;
1456 JSROOT.TFile.prototype.GetKey = function(keyname, cycle, getkey_callback) {
1457 // retrieve a key by its name and cycle in the list of keys
1458 // one should call_back when keys must be read first from the directory
1460 for (var i in this.fKeys) {
1461 if (this.fKeys[i]['fName
'] == keyname && this.fKeys[i]['fCycle
'] == cycle) {
1462 if (typeof getkey_callback == 'function') getkey_callback(this.fKeys[i]);
1463 return this.fKeys[i];
1467 var pos = keyname.lastIndexOf("/");
1468 // try to handle situation when object name contains slashed (bad practice anyway)
1470 var dirname = keyname.substr(0, pos);
1471 var subname = keyname.substr(pos+1);
1473 var dir = this.GetDir(dirname);
1474 if (dir!=null) return dir.GetKey(subname, cycle, getkey_callback);
1476 var dirkey = this.GetKey(dirname, 1);
1477 if ((dirkey!=null) && (typeof getkey_callback == 'function') &&
1478 (dirkey['fClassName
'].indexOf("TDirectory")==0)) {
1480 this.ReadObject(dirname, function(newdir) {
1481 if (newdir) newdir.GetKey(subname, cycle, getkey_callback);
1486 pos = keyname.lastIndexOf("/", pos-1);
1489 if (typeof call_back == 'function') call_back(null);
1493 JSROOT.TFile.prototype.ReadObjBuffer = function(key, callback) {
1494 // read and inflate object buffer described by its key
1498 this.Seek(key['fSeekKey
'] + key['fKeylen
'], this.ERelativeTo.kBeg);
1499 this.ReadBuffer(key['fNbytes
'] - key['fKeylen
'], function(blob1) {
1501 if (blob1==null) callback(null);
1505 if (key['fObjlen
'] <= key['fNbytes
']-key['fKeylen
']) {
1506 buf = new JSROOT.TBuffer(blob1, 0, file);
1508 var hdrsize = JSROOT.R__unzip_header(blob1, 0);
1509 if (hdrsize<0) return callback(null);
1510 var objbuf = JSROOT.R__unzip(hdrsize, blob1, 0);
1511 buf = new JSROOT.TBuffer(objbuf, 0, file);
1514 buf.fTagOffset = key.fKeylen;
1520 JSROOT.TFile.prototype.ReadObject = function(obj_name, cycle, user_call_back) {
1521 // Read any object from a root file
1522 // One could specify cycle number in the object name or as separate argument
1523 // Last argument should be callback function, while data reading from file is asynchron
1525 if (typeof cycle == 'function') { user_call_back = cycle; cycle = 1; }
1527 var pos = obj_name.lastIndexOf(";");
1529 cycle = parseInt(obj_name.slice(pos+1));
1530 obj_name = obj_name.slice(0, pos);
1533 if ((typeof cycle != 'number
') || (cycle<0)) cycle = 1;
1537 // we use callback version while in some cases we need to
1538 // read sub-directory to get list of keys
1539 // in such situation calls are asynchrone
1540 this.GetKey(obj_name, cycle, function(key) {
1543 if (typeof user_call_back == 'function') user_call_back(null);
1548 if ((key['fClassName
'] == 'TDirectory
' || key['fClassName
'] == 'TDirectoryFile
')) {
1550 var dir = file.GetDir(obj_name, cycle);
1552 if (typeof user_call_back == 'function') user_call_back(dir);
1557 file.ReadObjBuffer(key, function(buf) {
1559 if (typeof user_call_back == 'function') user_call_back(null);
1564 var dir = new JSROOT.TDirectory(file, obj_name, cycle);
1565 dir.StreamHeader(buf);
1566 if (dir.fSeekKeys) {
1567 dir.ReadKeys(user_call_back);
1569 if (typeof user_call_back == 'function') user_call_back(dir);
1576 buf.MapObject(1, obj); // tag object itself with id==1
1577 buf.ClassStreamer(obj, key['fClassName
']);
1579 if (typeof user_call_back == 'function') user_call_back(obj);
1580 }); // end of ReadObjBuffer callback
1581 }); // end of GetKey callback
1584 JSROOT.TFile.prototype.ExtractStreamerInfos = function(buf)
1589 buf.MapObject(1, lst);
1590 buf.ClassStreamer(lst, 'TList
');
1592 lst['_typename
'] = "TStreamerInfoList";
1594 this.fStreamerInfos = lst;
1597 JSROOT.TFile.prototype.ReadFormulas = function()
1599 for (var i in this.fKeys)
1600 if (this.fKeys[i]['fClassName
'] == 'TFormula
')
1601 this.ReadObject(this.fKeys[i]['fName
'], this.fKeys[i]['fCycle
'], function(obj) {
1602 JSROOT.addFormula(obj);
1606 JSROOT.TFile.prototype.ReadStreamerInfos = function(si_callback)
1608 if (this.fSeekInfo == 0 || this.fNbytesInfo == 0) return si_callback(null);
1609 this.Seek(this.fSeekInfo, this.ERelativeTo.kBeg);
1613 file.ReadBuffer(file.fNbytesInfo, function(blob1) {
1614 var buf = new JSROOT.TBuffer(blob1, 0, file);
1615 var key = file.ReadKey(buf);
1616 if (key == null) return si_callback(null);
1617 file.fKeys.push(key);
1619 file.ReadObjBuffer(key, function(blob2) {
1620 if (blob2==null) return si_callback(null);
1621 file.ExtractStreamerInfos(blob2);
1622 file.ReadFormulas();
1628 JSROOT.TFile.prototype.ReadKeys = function(readkeys_callback) {
1629 // read keys only in the root file
1631 if (typeof readkeys_callback != 'function')
1632 readkeys_callback = function() {};
1636 this.ReadBuffer(256, function(blob1) {
1637 var header = file.ReadHeader(blob1);
1638 if (header == null) return readkeys_callback(null);
1640 file.ReadBuffer(300, function(blob2) {
1641 if (blob2==null) return readkeys_callback(null);
1643 var buf = new JSROOT.TBuffer(blob2, 4, file); // skip the "root" file identifier
1644 file.fVersion = buf.ntou4();
1645 var headerLength = buf.ntou4();
1646 file.fBEGIN = headerLength;
1647 if (file.fVersion < 1000000) { //small file
1648 file.fEND = buf.ntou4();
1649 file.fSeekFree = buf.ntou4();
1650 file.fNbytesFree = buf.ntou4();
1651 var nfree = buf.ntoi4();
1652 file.fNbytesName = buf.ntou4();
1653 file.fUnits = buf.ntou1();
1654 file.fCompress = buf.ntou4();
1655 file.fSeekInfo = buf.ntou4();
1656 file.fNbytesInfo = buf.ntou4();
1657 } else { // new format to support large files
1658 file.fEND = buf.ntou8();
1659 file.fSeekFree = buf.ntou8();
1660 file.fNbytesFree = buf.ntou4();
1661 var nfree = buf.ntou4();
1662 file.fNbytesName = buf.ntou4();
1663 file.fUnits = buf.ntou1();
1664 file.fCompress = buf.ntou4();
1665 file.fSeekInfo = buf.ntou8();
1666 file.fNbytesInfo = buf.ntou4();
1668 file.fSeekDir = file.fBEGIN;
1670 //*-*-------------Read directory info
1672 var nbytes = file.fNbytesName + 22;
1673 nbytes += 4; // fDatimeC.Sizeof();
1674 nbytes += 4; // fDatimeM.Sizeof();
1675 nbytes += 18; // fUUID.Sizeof();
1676 // assume that the file may be above 2 Gbytes if file version is > 4
1677 if (file.fVersion >= 40000) nbytes += 12;
1679 file.Seek(file.fBEGIN, file.ERelativeTo.kBeg);
1680 file.ReadBuffer(Math.max(300, nbytes), function(blob3) {
1681 if (blob3==null) return readkeys_callback(null);
1683 var buf = new JSROOT.TBuffer(blob3, file.fNbytesName, file);
1684 var version = buf.ntou2();
1685 var versiondir = version%1000;
1686 buf.shift(8); // skip fDatimeC and fDatimeM
1687 file.fNbytesKeys = buf.ntou4();
1688 file.fNbytesName = buf.ntou4();
1689 if (version > 1000) {
1690 file.fSeekDir = buf.ntou8();
1691 file.fSeekParent = buf.ntou8();
1692 file.fSeekKeys = buf.ntou8();
1694 file.fSeekDir = buf.ntou4();
1695 file.fSeekParent = buf.ntou4();
1696 file.fSeekKeys = buf.ntou4();
1698 if (versiondir > 1) buf.o += 18; // skip fUUID
1700 //*-*---------read TKey::FillBuffer info
1701 buf.o = 4; // Skip NBytes;
1702 var keyversion = buf.ntoi2();
1703 // Skip ObjLen, DateTime, KeyLen, Cycle, SeekKey, SeekPdir
1704 if (keyversion > 1000) buf.shift(28); // Large files
1708 file.fTitle = buf.ReadTString();
1709 if (file.fNbytesName < 10 || this.fNbytesName > 10000) {
1710 console.log("Init : cannot read directory info of file " + file.fURL);
1711 return readkeys_callback(null);
1713 //*-* -------------Read keys of the top directory
1715 if (file.fSeekKeys <= 0) {
1716 console.log("Empty keys list - not supported" + file.fURL);
1717 return readkeys_callback(null);
1720 file.Seek(file.fSeekKeys, file.ERelativeTo.kBeg);
1721 file.ReadBuffer(file.fNbytesKeys, function(blob4) {
1722 if (blob4==null) return readkeys_callback(null);
1724 var buf = new JSROOT.TBuffer(blob4, 0, file);
1726 var key = file.ReadKey(buf);
1728 var nkeys = buf.ntoi4();
1729 for (var i = 0; i < nkeys; i++) {
1730 key = file.ReadKey(buf);
1731 file.fKeys.push(key);
1733 file.ReadStreamerInfos(readkeys_callback);
1744 JSROOT.TFile.prototype.ReadDirectory = function(dir_name, cycle, readdir_callback) {
1745 // read the directory content from a root file
1746 // do not read directory if it is already exists
1748 return this.ReadObject(dir_name, cycle, readdir_callback);
1752 JSROOT.TFile.prototype.GetStreamer = function(clname) {
1753 // return the streamer for the class 'clname
', from the list of streamers
1754 // or generate it from the streamer infos and add it to the list
1756 var streamer = this.fStreamers[clname];
1757 if (typeof(streamer) != 'undefined
') return streamer;
1761 if (this.fStreamerInfos)
1762 for (var i in this.fStreamerInfos.arr)
1763 if (this.fStreamerInfos.arr[i].fName == clname) {
1764 s_i = this.fStreamerInfos.arr[i];
1767 if (typeof s_i == 'undefined
') return null;
1769 this.fStreamers[clname] = new JSROOT.TStreamer(this);
1770 if (typeof(s_i['fElements
']) != 'undefined
') {
1771 var n_el = s_i['fElements
']['arr
'].length;
1772 for (var j=0;j<n_el;++j) {
1773 var element = s_i['fElements
']['arr
'][j];
1774 if (element['typename'] === 'BASE
') {
1775 // generate streamer for the base classes
1776 this.GetStreamer(element['fName
']);
1780 if (typeof(s_i['fElements
']) != 'undefined
') {
1781 var n_el = s_i['fElements
']['arr
'].length;
1782 for (var j=0;j<n_el;++j) {
1783 // extract streamer info for each class member
1784 var element = s_i['fElements
']['arr
'][j];
1786 streamer['typename'] = element['typename'];
1787 streamer['class'] = element['fName
'];
1788 streamer['cntname
'] = element['countName
'];
1789 streamer['type
'] = element['type
'];
1790 streamer['length
'] = element['length
'];
1792 this.fStreamers[clname][element['fName
']] = streamer;
1795 return this.fStreamers[clname];
1798 JSROOT.TFile.prototype.Delete = function() {
1799 if (this.fDirectories) this.fDirectories.splice(0, this.fDirectories.length);
1800 this.fDirectories = null;
1801 if (this.fKeys) this.fKeys.splice(0, this.fKeys.length);
1803 if (this.fStreamers) this.fStreamers.splice(0, this.fStreamers.length);
1804 this.fStreamers = null;
1806 this.fNbytesInfo = 0;
1807 this.fTagOffset = 0;
1812 // JSRootIOEvolution.js ends