5 if ( typeof define ===
"function" && define.amd ) {
6 define( [
'JSRootCore',
'rawinflate'], factory );
7 }
else if (typeof exports ===
'object' && typeof module !==
'undefined') {
8 require(
"./rawinflate.min.js");
9 factory(require(
"./JSRootCore.js"));
11 if (typeof JSROOT ==
'undefined')
12 throw new Error(
"JSROOT I/O requires JSRootCore.js",
"JSRootIOEvolution.js");
13 if (typeof JSROOT.ZIP ==
'undefined')
14 throw new Error(
"JSROOT I/O requires rawinflate.js",
"JSRootIOEvolution.js");
15 if (typeof JSROOT.IO ==
"object")
16 throw new Error(
"This JSROOT IO already loaded",
"JSRootIOEvolution.js");
23 JSROOT.sources.push(
"io");
26 kBase: 0, kOffsetL: 20, kOffsetP: 40,
27 kChar: 1, kShort: 2, kInt: 3, kLong: 4, kFloat: 5, kCounter: 6, kCharStar: 7, kDouble: 8, kDouble32: 9, kLegacyChar : 10,
28 kUChar: 11, kUShort: 12, kUInt: 13, kULong: 14, kBits: 15, kLong64: 16, kULong64: 17, kBool: 18, kFloat16: 19,
29 kObject: 61, kAny: 62, kObjectp: 63, kObjectP: 64, kTString: 65,
30 kTObject: 66, kTNamed: 67, kAnyp: 68, kAnyP: 69, kAnyPnoVT: 70, kSTLp: 71,
31 kSkip: 100, kSkipL: 120, kSkipP: 140, kConv: 200, kConvL: 220, kConvP: 240,
32 kSTL: 300, kSTLstring: 365, kStreamer: 500, kStreamLoop: 501,
34 kByteCountMask: 0x40000000,
35 kNewClassTag: 0xFFFFFFFF,
36 kClassMask: 0x80000000,
40 TypeNames : [
"BASE",
"char",
"short",
"int",
"long",
"float",
"int",
"const char*",
"double",
"Double32_t",
41 "char",
"unsigned char",
"unsigned short",
"unsigned",
"unsigned long",
"unsigned",
"Long64_t",
"ULong64_t",
"bool",
"Float16_t"],
44 kNotSTL: 0, kSTLvector: 1, kSTLlist: 2, kSTLdeque: 3, kSTLmap: 4, kSTLmultimap: 5,
45 kSTLset: 6, kSTLmultiset: 7, kSTLbitset: 8, kSTLforwardlist: 9,
46 kSTLunorderedset : 10, kSTLunorderedmultiset : 11, kSTLunorderedmap : 12,
47 kSTLunorderedmultimap : 13, kSTLend : 14,
50 StlNames: [
"",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset"],
53 kStreamedMemberWise: JSROOT.BIT(14),
55 kSplitCollectionOfPointers: 100,
67 kIsReferenced: JSROOT.BIT(4),
68 kHasUUID: JSROOT.BIT(5),
70 IsInteger:
function(typ) {
return ((typ>=this.kChar) && (typ<=this.kLong)) || (typ===this.kCounter) ||
71 ((typ>=this.kLegacyChar) && (typ<=this.kBool)); },
73 IsNumeric:
function(typ) {
return (typ>0) && (typ<=this.kBool) && (typ!==this.kCharStar); },
75 GetTypeId:
function(typname, norecursion) {
78 case "Bool_t":
return JSROOT.IO.kBool;
81 case "Char_t":
return JSROOT.IO.kChar;
86 case "Short_t":
return JSROOT.IO.kShort;
89 case "Int_t":
return JSROOT.IO.kInt;
91 case "Long_t":
return JSROOT.IO.kLong;
93 case "Float_t":
return JSROOT.IO.kFloat;
95 case "Double_t":
return JSROOT.IO.kDouble;
97 case "UChar_t":
return JSROOT.IO.kUChar;
98 case "unsigned short":
99 case "UShort_t":
return JSROOT.IO.kUShort;
102 case "UInt_t":
return JSROOT.IO.kUInt;
103 case "unsigned long":
104 case "ULong_t":
return JSROOT.IO.kULong;
107 case "Long64_t":
return JSROOT.IO.kLong64;
109 case "unsigned long long":
110 case "ULong64_t":
return JSROOT.IO.kULong64;
111 case "Double32_t":
return JSROOT.IO.kDouble32;
112 case "Float16_t":
return JSROOT.IO.kFloat16;
115 case "const Char_t*":
return JSROOT.IO.kCharStar;
119 var replace = JSROOT.IO.CustomStreamers[typname];
120 if (typeof replace ===
"string")
return JSROOT.IO.GetTypeId(replace,
true);
126 GetTypeSize:
function(typname) {
128 case JSROOT.IO.kBool:
return 1;
129 case JSROOT.IO.kChar:
return 1;
130 case JSROOT.IO.kShort :
return 2;
131 case JSROOT.IO.kInt:
return 4;
132 case JSROOT.IO.kLong:
return 8;
133 case JSROOT.IO.kFloat:
return 4;
134 case JSROOT.IO.kDouble:
return 8;
135 case JSROOT.IO.kUChar:
return 1;
136 case JSROOT.IO.kUShort:
return 2;
137 case JSROOT.IO.kUInt:
return 4;
138 case JSROOT.IO.kULong:
return 8;
139 case JSROOT.IO.kLong64:
return 8;
140 case JSROOT.IO.kULong64:
return 8;
147 JSROOT.addUserStreamer =
function(type, user_streamer) {
148 JSROOT.IO.CustomStreamers[type] = user_streamer;
151 JSROOT.R__unzip =
function(arr, tgtsize, noalert, src_shift) {
154 var totallen = arr.byteLength, curr = src_shift || 0, fullres = 0, tgtbuf = null, HDRSIZE = 9;
156 function getChar(o) {
return String.fromCharCode(arr.getUint8(o)); }
158 function getCode(o) {
return arr.getUint8(o); }
160 while (fullres < tgtsize) {
162 var fmt =
"unknown", off = 0, CHKSUM = 0;
164 if (curr + HDRSIZE >= totallen) {
165 if (!noalert) JSROOT.alert(
"Error R__unzip: header size exceeds buffer size");
169 if (getChar(curr) ==
'Z' && getChar(curr+1) ==
'L' && getCode(curr+2) == 8) { fmt =
"new"; off = 2; }
else
170 if (getChar(curr) ==
'C' && getChar(curr+1) ==
'S' && getCode(curr+2) == 8) { fmt =
"old"; off = 0; }
else
171 if (getChar(curr) ==
'X' && getChar(curr+1) ==
'Z') fmt =
"LZMA";
else
172 if (getChar(curr) ==
'L' && getChar(curr+1) ==
'4') { fmt =
"LZ4"; off = 0; CHKSUM = 8; }
205 if ((fmt !==
"new") && (fmt !==
"old") && (fmt !==
"LZ4")) {
206 if (!noalert) JSROOT.alert(
"R__unzip: " + fmt +
" format is not supported!");
210 var srcsize = HDRSIZE + ((getCode(curr+3) & 0xff) | ((getCode(curr+4) & 0xff) << 8) | ((getCode(curr+5) & 0xff) << 16));
212 var uint8arr =
new Uint8Array(arr.buffer, arr.byteOffset + curr + HDRSIZE + off + CHKSUM, Math.min(arr.byteLength - curr - HDRSIZE - off - CHKSUM, srcsize - HDRSIZE - CHKSUM));
215 if (!tgtbuf) tgtbuf =
new ArrayBuffer(tgtsize);
217 var tgt8arr =
new Uint8Array(tgtbuf, fullres);
219 var reslen = (fmt ===
"LZ4") ? JSROOT.LZ4.uncompress(uint8arr, tgt8arr)
220 : JSROOT.ZIP.inflate(uint8arr, tgt8arr);
221 if (reslen<=0)
break;
227 if (fullres !== tgtsize) {
228 if (!noalert) JSROOT.alert(
"R__unzip: fail to unzip data expects " + tgtsize +
" , got " + fullres);
232 return new DataView(tgtbuf);
237 function TBuffer(arr, pos, file, length) {
239 this._typename =
"TBuffer";
243 this.length = length || (arr ? arr.byteLength : 0);
244 this.ClearObjectMap();
246 this.last_read_version = 0;
250 TBuffer.prototype.locate =
function(pos) {
254 TBuffer.prototype.shift =
function(cnt) {
258 TBuffer.prototype.remain =
function() {
259 return this.length - this.o;
262 TBuffer.prototype.GetMappedObject =
function(tag) {
263 return this.fObjectMap[tag];
266 TBuffer.prototype.MapObject =
function(tag, obj) {
268 this.fObjectMap[tag] = obj;
271 TBuffer.prototype.MapClass =
function(tag, classname) {
272 this.fClassMap[tag] = classname;
275 TBuffer.prototype.GetMappedClass =
function(tag) {
276 if (tag in this.fClassMap)
return this.fClassMap[tag];
280 TBuffer.prototype.ClearObjectMap =
function() {
281 this.fObjectMap = {};
283 this.fObjectMap[0] = null;
284 this.fDisplacement = 0;
287 TBuffer.prototype.ReadVersion =
function() {
289 var ver = {}, bytecnt = this.ntou4();
291 if (bytecnt & JSROOT.IO.kByteCountMask)
292 ver.bytecnt = bytecnt - JSROOT.IO.kByteCountMask - 2;
296 this.last_read_version = ver.val = this.ntoi2();
297 this.last_read_checksum = 0;
300 if ((ver.val <= 0) && ver.bytecnt && (ver.bytecnt>=4)) {
301 ver.checksum = this.ntou4();
302 if (!this.fFile.FindSinfoCheckum(ver.checksum)) {
307 this.last_read_checksum = ver.checksum;
313 TBuffer.prototype.CheckBytecount =
function(ver, where) {
314 if ((ver.bytecnt !== undefined) && (ver.off + ver.bytecnt !== this.o)) {
317 console.log(
"Missmatch in " + where +
" bytecount expected = " + ver.bytecnt +
" got = " + (
this.o-ver.off));
319 this.o = ver.off + ver.bytecnt;
325 TBuffer.prototype.ReadTString =
function() {
328 var len = this.ntou1();
330 if (len == 255) len = this.ntou4();
331 if (len==0)
return "";
336 return (this.codeAt(pos) == 0) ?
'' : this.substring(pos, pos + len);
339 TBuffer.prototype.ReadFastString =
function(n) {
343 var res =
"", code, closed =
false;
344 for (var i = 0; (n < 0) || (i < n); ++i) {
346 if (code==0) { closed =
true;
if (n<0)
break; }
347 if (!closed) res += String.fromCharCode(code);
353 TBuffer.prototype.ntou1 =
function() {
354 return this.arr.getUint8(this.o++);
357 TBuffer.prototype.ntou2 =
function() {
358 var o = this.o; this.o+=2;
359 return this.arr.getUint16(o);
362 TBuffer.prototype.ntou4 =
function() {
363 var o = this.o; this.o+=4;
364 return this.arr.getUint32(o);
367 TBuffer.prototype.ntou8 =
function() {
368 var high = this.arr.getUint32(this.o); this.o+=4;
369 var low = this.arr.getUint32(this.o); this.o+=4;
370 return high * 0x100000000 + low;
373 TBuffer.prototype.ntoi1 =
function() {
374 return this.arr.getInt8(this.o++);
377 TBuffer.prototype.ntoi2 =
function() {
378 var o = this.o; this.o+=2;
379 return this.arr.getInt16(o);
382 TBuffer.prototype.ntoi4 =
function() {
383 var o = this.o; this.o+=4;
384 return this.arr.getInt32(o);
387 TBuffer.prototype.ntoi8 =
function() {
388 var high = this.arr.getUint32(this.o); this.o+=4;
389 var low = this.arr.getUint32(this.o); this.o+=4;
390 if (high < 0x80000000)
return high * 0x100000000 + low;
391 return -1 - ((~high) * 0x100000000 + ~low);
394 TBuffer.prototype.ntof =
function() {
395 var o = this.o; this.o+=4;
396 return this.arr.getFloat32(o);
399 TBuffer.prototype.ntod =
function() {
400 var o = this.o; this.o+=8;
401 return this.arr.getFloat64(o);
404 TBuffer.prototype.ReadFastArray =
function(n, array_type) {
407 var array, i = 0, o = this.o, view = this.arr;
408 switch (array_type) {
409 case JSROOT.IO.kDouble:
410 array =
new Float64Array(n);
411 for (; i < n; ++i, o+=8)
412 array[i] = view.getFloat64(o);
414 case JSROOT.IO.kFloat:
415 array =
new Float32Array(n);
416 for (; i < n; ++i, o+=4)
417 array[i] = view.getFloat32(o);
419 case JSROOT.IO.kLong:
420 case JSROOT.IO.kLong64:
421 array =
new Float64Array(n);
423 array[i] = this.ntoi8();
425 case JSROOT.IO.kULong:
426 case JSROOT.IO.kULong64:
427 array =
new Float64Array(n);
429 array[i] = this.ntou8();
432 case JSROOT.IO.kCounter:
433 array =
new Int32Array(n);
434 for (; i < n; ++i, o+=4)
435 array[i] = view.getInt32(o);
437 case JSROOT.IO.kBits:
438 case JSROOT.IO.kUInt:
439 array =
new Uint32Array(n);
440 for (; i < n; ++i, o+=4)
441 array[i] = view.getUint32(o);
443 case JSROOT.IO.kShort:
444 array =
new Int16Array(n);
445 for (; i < n; ++i, o+=2)
446 array[i] = view.getInt16(o);
448 case JSROOT.IO.kUShort:
449 array =
new Uint16Array(n);
450 for (; i < n; ++i, o+=2)
451 array[i] = view.getUint16(o);
453 case JSROOT.IO.kChar:
454 array =
new Int8Array(n);
456 array[i] = view.getInt8(o++);
458 case JSROOT.IO.kBool:
459 case JSROOT.IO.kUChar:
460 array =
new Uint8Array(n);
462 array[i] = view.getUint8(o++);
464 case JSROOT.IO.kTString:
465 array =
new Array(n);
467 array[i] = this.ReadTString();
469 case JSROOT.IO.kDouble32:
470 throw new Error(
'kDouble32 should not be used in ReadFastArray');
471 case JSROOT.IO.kFloat16:
472 throw new Error(
'kFloat16 should not be used in ReadFastArray');
474 array =
new Uint32Array(n);
475 for (; i < n; ++i, o+=4)
476 array[i] = view.getUint32(o);
485 TBuffer.prototype.can_extract =
function(place) {
486 for (var n=0;n<place.length;n+=2)
487 if (place[n] + place[n+1] > this.length)
return false;
491 TBuffer.prototype.extract =
function(place) {
492 if (!this.arr || !this.arr.buffer || !
this.can_extract(place))
return null;
493 if (place.length===2)
return new DataView(this.arr.buffer,
this.arr.byteOffset + place[0], place[1]);
495 var res =
new Array(place.length/2);
497 for (var n=0;n<place.length;n+=2)
498 res[n/2] =
new DataView(this.arr.buffer,
this.arr.byteOffset + place[n], place[n+1]);
503 TBuffer.prototype.codeAt =
function(pos) {
504 return this.arr.getUint8(pos);
507 TBuffer.prototype.substring =
function(beg, end) {
509 for (var n=beg;n<end;++n)
510 res += String.fromCharCode(
this.arr.getUint8(n));
515 JSROOT.IO.GetArrayKind =
function(type_name) {
519 if ((type_name ===
"TString") || (type_name ===
"string") ||
520 (JSROOT.IO.CustomStreamers[type_name] ===
'TString'))
return 0;
521 if ((type_name.length < 7) || (type_name.indexOf(
"TArray")!==0))
return -1;
522 if (type_name.length == 7)
523 switch (type_name[6]) {
524 case 'I':
return JSROOT.IO.kInt;
525 case 'D':
return JSROOT.IO.kDouble;
526 case 'F':
return JSROOT.IO.kFloat;
527 case 'S':
return JSROOT.IO.kShort;
528 case 'C':
return JSROOT.IO.kChar;
529 case 'L':
return JSROOT.IO.kLong;
533 return type_name ==
"TArrayL64" ? JSROOT.IO.kLong64 : -1;
536 TBuffer.prototype.ReadNdimArray =
function(handle, func) {
537 var ndim = handle.fArrayDim, maxindx = handle.fMaxIndex, res;
538 if ((ndim<1) && (handle.fArrayLength>0)) { ndim = 1; maxindx = [handle.fArrayLength]; }
539 if (handle.minus1) --ndim;
541 if (ndim<1)
return func(
this, handle);
544 res =
new Array(maxindx[0]);
545 for (var n=0;n<maxindx[0];++n)
546 res[n] = func(
this, handle);
549 res =
new Array(maxindx[0]);
550 for (var n=0;n<maxindx[0];++n) {
551 var res2 =
new Array(maxindx[1]);
552 for (var k=0;k<maxindx[1];++k)
553 res2[k] = func(
this, handle);
557 var indx = [], arr = [], k;
558 for (k=0; k<ndim; ++k) { indx[k] = 0; arr[k] = []; }
560 while (indx[0] < maxindx[0]) {
562 arr[k].push(func(
this, handle));
564 while ((indx[k] === maxindx[k]) && (k>0)) {
566 arr[k-1].push(arr[k]);
576 TBuffer.prototype.ReadTKey =
function(key) {
578 this.ClassStreamer(key,
'TKey');
579 var name = key.fName.replace(/[
'"]/g,'');
580 if (name !== key.fName) {
581 key.fRealName = key.fName;
587 TBuffer.prototype.ReadBasketEntryOffset = function(basket, offset) {
588 // this is remaining part of TBasket streamer to decode fEntryOffset
589 // after unzipping of the TBasket data
591 this.locate(basket.fLast - offset);
593 if (this.remain() <= 0) {
594 if (!basket.fEntryOffset && (basket.fNevBuf <= 1)) basket.fEntryOffset = [ basket.fKeylen ];
595 if (!basket.fEntryOffset) console.warn("No fEntryOffset when expected for basket with", basket.fNevBuf, "entries");
599 var nentries = this.ntoi4();
600 // there is error in file=reco_103.root&item=Events;2/PCaloHits_g4SimHits_EcalHitsEE_Sim.&opt=dump;num:10;first:101
601 // it is workaround, but normally I/O should fail here
602 if ((nentries < 0) || (nentries > this.remain()*4)) {
603 console.error("Error when reading entries offset from basket fNevBuf", basket.fNevBuf, "remains", this.remain(), "want to read", nentries);
604 if (basket.fNevBuf <= 1) basket.fEntryOffset = [ basket.fKeylen ];
608 basket.fEntryOffset = this.ReadFastArray(nentries, JSROOT.IO.kInt);
609 if (!basket.fEntryOffset) basket.fEntryOffset = [ basket.fKeylen ];
611 if (this.remain() > 0)
612 basket.fDisplacement = this.ReadFastArray(this.ntoi4(), JSROOT.IO.kInt);
614 basket.fDisplacement = undefined;
617 TBuffer.prototype.ReadClass = function() {
618 // read class definition from I/O buffer
619 var classInfo = { name: -1 },
624 if (!(bcnt & JSROOT.IO.kByteCountMask) || (bcnt == JSROOT.IO.kNewClassTag)) {
630 if (!(tag & JSROOT.IO.kClassMask)) {
631 classInfo.objtag = tag + this.fDisplacement; // indicate that we have deal with objects tag
634 if (tag == JSROOT.IO.kNewClassTag) {
635 // got a new class description followed by a new object
636 classInfo.name = this.ReadFastString(-1);
638 if (this.GetMappedClass(this.fTagOffset + startpos + JSROOT.IO.kMapOffset) === -1)
639 this.MapClass(this.fTagOffset + startpos + JSROOT.IO.kMapOffset, classInfo.name);
641 // got a tag to an already seen class
642 var clTag = (tag & ~JSROOT.IO.kClassMask) + this.fDisplacement;
643 classInfo.name = this.GetMappedClass(clTag);
645 if (classInfo.name === -1)
646 JSROOT.alert("Did not found class with tag " + clTag);
652 TBuffer.prototype.ReadObjectAny = function() {
653 var objtag = this.fTagOffset + this.o + JSROOT.IO.kMapOffset,
654 clRef = this.ReadClass();
656 // class identified as object and should be handled so
657 if ('objtag
' in clRef)
658 return this.GetMappedObject(clRef.objtag);
660 if (clRef.name === -1) return null;
662 var arrkind = JSROOT.IO.GetArrayKind(clRef.name), obj;
665 obj = this.ReadTString();
668 // reading array, can map array only afterwards
669 obj = this.ReadFastArray(this.ntou4(), arrkind);
670 this.MapObject(objtag, obj);
672 // reading normal object, should map before to
674 this.MapObject(objtag, obj);
675 this.ClassStreamer(obj, clRef.name);
681 TBuffer.prototype.ClassStreamer = function(obj, classname) {
683 if (obj._typename === undefined) obj._typename = classname;
685 var direct = JSROOT.IO.DirectStreamers[classname];
691 var ver = this.ReadVersion();
693 var streamer = this.fFile.GetStreamer(classname, ver);
695 if (streamer !== null) {
697 for (var n = 0; n < streamer.length; ++n)
698 streamer[n].func(this, obj);
701 // just skip bytes belonging to not-recognized object
702 // console.warn('skip
object ', classname);
704 JSROOT.addMethods(obj);
707 this.CheckBytecount(ver, classname);
713 // =======================================================================
715 JSROOT.CreateTBuffer = function(blob, pos, file, length) {
716 return new TBuffer(blob, pos, file, length);
719 JSROOT.ReconstructObject = function(class_name, obj_rawdata, sinfo_rawdata) {
720 // method can be used to reconstruct ROOT object from binary buffer
721 // Buffer can be requested from online server with request like:
722 // http://localhost:8080/Files/job1.root/hpx/root.bin
723 // One also requires buffer with streamer infos, requested with command
724 // http://localhost:8080/StreamerInfo/root.bin
725 // And one should provide class name of the object
727 // Method provided for convenience only to see how binary JSROOT.IO works.
728 // It is strongly recommended to use JSON representation:
729 // http://localhost:8080/Files/job1.root/hpx/root.json
731 var file = new TFile;
732 var buf = JSROOT.CreateTBuffer(sinfo_rawdata, 0, file);
733 file.ExtractStreamerInfos(buf);
737 buf = JSROOT.CreateTBuffer(obj_rawdata, 0, file);
738 buf.MapObject(obj, 1);
739 buf.ClassStreamer(obj, class_name);
744 // ==============================================================================
746 // A class that reads a TDirectory from a buffer.
749 function TDirectory(file, dirname, cycle) {
751 this._typename = "TDirectory";
752 this.dir_name = dirname;
753 this.dir_cycle = cycle;
758 TDirectory.prototype.GetKey = function(keyname, cycle, call_back) {
759 // retrieve a key by its name and cycle in the list of keys
761 if (typeof cycle != 'number
') cycle = -1;
763 for (var i = 0; i < this.fKeys.length; ++i) {
764 var key = this.fKeys[i];
765 if (!key || (key.fName!==keyname)) continue;
766 if (key.fCycle == cycle) { bestkey = key; break; }
767 if ((cycle < 0) && (!bestkey || (key.fCycle > bestkey.fCycle))) bestkey = key;
770 JSROOT.CallBack(call_back, bestkey);
774 var pos = keyname.lastIndexOf("/");
775 // try to handle situation when object name contains slashed (bad practice anyway)
777 var dirname = keyname.substr(0, pos),
778 subname = keyname.substr(pos+1),
779 dirkey = this.GetKey(dirname);
781 if ((dirkey!==null) && (typeof call_back == 'function') &&
782 (dirkey.fClassName.indexOf("TDirectory")==0)) {
784 this.fFile.ReadObject(this.dir_name + "/" + dirname, 1, function(newdir) {
785 if (newdir) newdir.GetKey(subname, cycle, call_back);
790 pos = keyname.lastIndexOf("/", pos-1);
793 JSROOT.CallBack(call_back, null);
797 TDirectory.prototype.ReadObject = function(obj_name, cycle, user_call_back) {
798 this.fFile.ReadObject(this.dir_name + "/" + obj_name, cycle, user_call_back);
801 TDirectory.prototype.ReadKeys = function(objbuf, readkeys_callback) {
803 objbuf.ClassStreamer(this, 'TDirectory
');
805 if ((this.fSeekKeys <= 0) || (this.fNbytesKeys <= 0))
806 return JSROOT.CallBack(readkeys_callback, this);
808 var dir = this, file = this.fFile;
810 file.ReadBuffer([this.fSeekKeys, this.fNbytesKeys], function(blob) {
811 if (!blob) return JSROOT.CallBack(readkeys_callback,null);
813 //*-* -------------Read keys of the top directory
815 var buf = JSROOT.CreateTBuffer(blob, 0, file);
818 var nkeys = buf.ntoi4();
820 for (var i = 0; i < nkeys; ++i)
821 dir.fKeys.push(buf.ReadTKey());
823 file.fDirectories.push(dir);
825 JSROOT.CallBack(readkeys_callback, dir);
829 // ==============================================================================
830 // A class that reads ROOT files.
833 // A ROOT file is a suite of consecutive data records (TKey's) with
863 function TFile(url, newfile_callback) {
864 this._typename =
"TFile";
868 this.fAcceptRanges =
true;
869 this.fUseStampPar =
"stamp="+(
new Date).getTime();
870 this.fFileContent = null;
872 this.fMaxRanges = 200;
873 this.fDirectories = [];
876 this.fNbytesInfo = 0;
879 this.fStreamerInfos = null;
881 this.fStreamers = [];
882 this.fBasicTypes = {};
884 if (typeof this.fURL !=
'string')
return this;
886 if (this.fURL[this.fURL.length-1] ===
"+") {
887 this.fURL = this.fURL.substr(0, this.fURL.length-1);
888 this.fAcceptRanges =
false;
891 if (this.fURL[this.fURL.length-1] ===
"-") {
892 this.fURL = this.fURL.substr(0, this.fURL.length-1);
893 this.fUseStampPar =
false;
896 if (this.fURL.indexOf(
"file://")==0) {
897 this.fUseStampPar =
false;
898 this.fAcceptRanges =
false;
901 var pos = Math.max(this.fURL.lastIndexOf(
"/"), this.fURL.lastIndexOf(
"\\"));
902 this.fFileName = pos>=0 ? this.fURL.substr(pos+1) : this.fURL;
904 if (!this.fAcceptRanges) {
905 this.ReadKeys(newfile_callback);
908 JSROOT.NewHttpRequest(this.fURL,
"head",
function(res) {
910 return JSROOT.CallBack(newfile_callback, null);
912 var accept_ranges = res.getResponseHeader(
"Accept-Ranges");
913 if (!accept_ranges) file.fAcceptRanges =
false;
914 var len = res.getResponseHeader(
"Content-Length");
915 if (len) file.fEND = parseInt(len);
916 else file.fAcceptRanges =
false;
917 file.ReadKeys(newfile_callback);
926 TFile.prototype.ReadBuffer =
function(place, result_callback, filename, progress_callback) {
928 if ((this.fFileContent!==null) && !filename && (!this.fAcceptRanges || this.fFileContent.can_extract(place)))
929 return result_callback(this.fFileContent.extract(place));
931 var file =
this, fileurl = file.fURL,
932 first = 0, last = 0, blobs = [], read_callback;
934 if (filename && (typeof filename ===
'string') && (filename.length>0)) {
935 var pos = fileurl.lastIndexOf(
"/");
936 fileurl = (pos<0) ? filename : fileurl.substr(0,pos+1) + filename;
939 function send_new_request(increment) {
943 last = Math.min(first + file.fMaxRanges*2, place.length);
944 if (first>=place.length)
return result_callback(blobs);
947 var fullurl = fileurl, ranges =
"bytes", totalsz = 0;
949 if (file.fUseStampPar) fullurl += ((fullurl.indexOf(
'?')<0) ?
"?" :
"&") + file.fUseStampPar;
951 for (var n=first;n<last;n+=2) {
952 ranges += (n>first ?
"," :
"=") + (place[n] +
"-" + (place[n] + place[n+1] - 1));
953 totalsz += place[n+1];
955 if (last-first>2) totalsz += (last-first)*60;
957 var xhr = JSROOT.NewHttpRequest(fullurl,
"buf", read_callback);
959 if (file.fAcceptRanges) {
960 xhr.setRequestHeader(
"Range", ranges);
961 xhr.expected_size = Math.max(Math.round(1.1*totalsz), totalsz+200);
964 if (progress_callback && (typeof xhr.addEventListener ===
'function')) {
965 var sum1 = 0, sum2 = 0, sum_total = 0;
966 for (var n=1;n<place.length;n+=2) {
968 if (n<first) sum1+=place[n];
969 if (n<last) sum2+=place[n];
971 if (!sum_total) sum_total = 1;
973 var progress_offest = sum1/sum_total, progress_this = (sum2-sum1)/sum_total;
974 xhr.addEventListener(
"progress",
function(oEvent) {
975 if (oEvent.lengthComputable)
976 progress_callback(progress_offest + progress_this*oEvent.loaded/oEvent.total);
983 read_callback =
function(res) {
985 if (!res && file.fUseStampPar && (place[0]===0) && (place.length===2)) {
987 file.fUseStampPar =
false;
988 return send_new_request();
991 if (res && (place[0]===0) && (place.length===2) && !file.fFileContent) {
994 file.fFileContent = JSROOT.CreateTBuffer((typeof res ==
'string') ? res :
new DataView(res));
996 if (!file.fAcceptRanges)
997 file.fEND = file.fFileContent.length;
999 return result_callback(file.fFileContent.extract(place));
1003 if ((first===0) && (last > 2) && (file.fMaxRanges>1)) {
1006 if (last/2 > 200) file.fMaxRanges = 200;
else
1007 if (last/2 > 50) file.fMaxRanges = 50;
else
1008 if (last/2 > 20) file.fMaxRanges = 20;
else
1009 if (last/2 > 5) file.fMaxRanges = 5;
else file.fMaxRanges = 1;
1010 last = Math.min(last, file.fMaxRanges*2);
1012 return send_new_request();
1015 return result_callback(null);
1019 if (last - first === 2) {
1020 var b =
new DataView(res);
1021 if (place.length===2)
return result_callback(b);
1023 return send_new_request(
true);
1027 var hdr = this.getResponseHeader(
'Content-Type'),
1028 ismulti = (typeof hdr ===
'string') && (hdr.indexOf(
'multipart')>=0),
1029 view =
new DataView(res);
1034 var hdr_range = this.getResponseHeader(
'Content-Range'), segm_start = 0, segm_last = -1;
1036 if (hdr_range && hdr_range.indexOf(
"bytes")>=0) {
1037 var parts = hdr_range.substr(hdr_range.indexOf(
"bytes") + 6).split(/[\s-\/]+/);
1038 if (parts.length===3) {
1039 segm_start = parseInt(parts[0]);
1040 segm_last = parseInt(parts[1]);
1041 if (isNaN(segm_start) || isNaN(segm_last) || (segm_start > segm_last)) {
1042 segm_start = 0; segm_last = -1;
1047 var canbe_single_segment = (segm_start<=segm_last);
1048 for(var n=first;n<last;n+=2)
1049 if ((place[n]<segm_start) || (place[n] + place[n+1] -1 > segm_last))
1050 canbe_single_segment =
false;
1052 if (canbe_single_segment) {
1053 for (var n=first;n<last;n+=2)
1054 blobs.push(
new DataView(res, place[n]-segm_start, place[n+1]));
1055 return send_new_request(
true);
1058 console.error(
'Server returns normal response when multipart was requested, disable multirange support');
1060 if ((file.fMaxRanges === 1) || (first!==0))
return result_callback(null);
1062 file.fMaxRanges = 1;
1063 last = Math.min(last, file.fMaxRanges*2);
1065 return send_new_request();
1070 var indx = hdr.indexOf(
"boundary="), boundary =
"", n = first, o = 0;
1072 boundary = hdr.substr(indx+9);
1073 if ((boundary[0] ==
'"') && (boundary[boundary.length-1] ==
'"'))
1074 boundary = boundary.substr(1, boundary.length-2);
1075 boundary =
"--" + boundary;
1076 }
else console.error(
'Did not found boundary id in the response header');
1080 var code1, code2 = view.getUint8(o), nline = 0, line =
"",
1081 finish_header =
false, segm_start = 0, segm_last = -1;
1083 while((o < view.byteLength-1) && !finish_header && (nline<5)) {
1085 code2 = view.getUint8(o+1);
1087 if ((code1==13) && (code2==10)) {
1088 if ((line.length>2) && (line.substr(0,2)==
'--') && (line !== boundary)) {
1089 console.error(
'Decode multipart message, expect boundary ', boundary,
'got ', line);
1090 return result_callback(null);
1093 line = line.toLowerCase();
1095 if ((line.indexOf(
"content-range")>=0) && (line.indexOf(
"bytes") > 0)) {
1096 var parts = line.substr(line.indexOf(
"bytes") + 6).split(/[\s-\/]+/);
1097 if (parts.length===3) {
1098 segm_start = parseInt(parts[0]);
1099 segm_last = parseInt(parts[1]);
1100 if (isNaN(segm_start) || isNaN(segm_last) || (segm_start > segm_last)) {
1101 segm_start = 0; segm_last = -1;
1104 console.error(
'Fail to decode content-range', line, parts);
1108 if ((nline > 1) && (line.length===0)) finish_header =
true;
1110 o++; nline++; line =
"";
1111 code2 = view.getUint8(o+1);
1113 line += String.fromCharCode(code1);
1118 if (!finish_header) {
1119 console.error(
'Cannot decode header in multipart message ');
1120 return result_callback(null);
1123 if (segm_start > segm_last) {
1125 blobs.push(
new DataView(res, o, place[n+1]));
1129 while ((n<last) && (place[n] >= segm_start) && (place[n] + place[n+1] - 1 <= segm_last)) {
1130 blobs.push(
new DataView(res, o + place[n] - segm_start, place[n+1]));
1134 o += (segm_last-segm_start+1);
1138 send_new_request(
true);
1141 send_new_request(
true);
1147 TFile.prototype.GetDir =
function(dirname, cycle) {
1149 if ((cycle === undefined) && (typeof dirname ==
'string')) {
1150 var pos = dirname.lastIndexOf(
';');
1151 if (pos>0) { cycle = parseInt(dirname.substr(pos+1)); dirname = dirname.substr(0,pos); }
1154 for (var j=0; j < this.fDirectories.length; ++j) {
1155 var dir = this.fDirectories[j];
1156 if (dir.dir_name != dirname)
continue;
1157 if ((cycle !== undefined) && (dir.dir_cycle !== cycle))
continue;
1166 TFile.prototype.GetKey =
function(keyname, cycle, getkey_callback) {
1168 if (typeof cycle !=
'number') cycle = -1;
1170 for (var i = 0; i < this.fKeys.length; ++i) {
1171 var key = this.fKeys[i];
1172 if (!key || (key.fName!==keyname))
continue;
1173 if (key.fCycle == cycle) { bestkey = key;
break; }
1174 if ((cycle < 0) && (!bestkey || (key.fCycle > bestkey.fCycle))) bestkey = key;
1177 JSROOT.CallBack(getkey_callback, bestkey);
1181 var pos = keyname.lastIndexOf(
"/");
1184 var dirname = keyname.substr(0, pos),
1185 subname = keyname.substr(pos+1),
1186 dir = this.GetDir(dirname);
1188 if (dir)
return dir.GetKey(subname, cycle, getkey_callback);
1190 var dirkey = this.GetKey(dirname);
1191 if (dirkey && getkey_callback && (dirkey.fClassName.indexOf(
"TDirectory")==0)) {
1192 this.ReadObject(dirname,
function(newdir) {
1193 if (newdir) newdir.GetKey(subname, cycle, getkey_callback);
1198 pos = keyname.lastIndexOf(
"/", pos-1);
1201 JSROOT.CallBack(getkey_callback, null);
1207 TFile.prototype.ReadObjBuffer =
function(key, callback) {
1211 this.ReadBuffer([key.fSeekKey + key.fKeylen, key.fNbytes - key.fKeylen],
function(blob1) {
1213 if (!blob1)
return callback(null);
1217 if (key.fObjlen <= key.fNbytes - key.fKeylen) {
1218 buf = JSROOT.CreateTBuffer(blob1, 0, file);
1220 var objbuf = JSROOT.R__unzip(blob1, key.fObjlen);
1221 if (!objbuf)
return callback(null);
1222 buf = JSROOT.CreateTBuffer(objbuf, 0, file);
1225 buf.fTagOffset = key.fKeylen;
1233 TFile.prototype.AddReadTree =
function(obj) {
1235 if (JSROOT.TreeMethods)
1236 return JSROOT.extend(obj, JSROOT.TreeMethods);
1238 if (this.readTrees===undefined) this.readTrees = [];
1240 if (this.readTrees.indexOf(obj)<0) this.readTrees.push(obj);
1251 TFile.prototype.ReadObject =
function(obj_name, cycle, user_call_back, only_dir) {
1252 if (typeof cycle ==
'function') { user_call_back = cycle; cycle = -1; }
1254 var pos = obj_name.lastIndexOf(
";");
1256 cycle = parseInt(obj_name.slice(pos+1));
1257 obj_name = obj_name.slice(0, pos);
1260 if (typeof cycle !=
'number') cycle = -1;
1262 while (obj_name.length && (obj_name[0] ==
"/")) obj_name = obj_name.substr(1);
1269 this.GetKey(obj_name, cycle,
function(key) {
1272 return JSROOT.CallBack(user_call_back, null);
1274 if ((obj_name==
"StreamerInfo") && (key.fClassName==
"TList"))
1275 return file.fStreamerInfos;
1278 if ((key.fClassName ==
'TDirectory' || key.fClassName ==
'TDirectoryFile')) {
1280 var dir = file.GetDir(obj_name, cycle);
1281 if (dir)
return JSROOT.CallBack(user_call_back, dir);
1284 if (!isdir && only_dir)
1285 return JSROOT.CallBack(user_call_back, null);
1287 file.ReadObjBuffer(key,
function(buf) {
1288 if (!buf)
return JSROOT.CallBack(user_call_back, null);
1291 var dir =
new TDirectory(file, obj_name, cycle);
1292 dir.fTitle = key.fTitle;
1293 return dir.ReadKeys(buf, user_call_back);
1297 buf.MapObject(1, obj);
1298 buf.ClassStreamer(obj, key.fClassName);
1300 if ((key.fClassName===
'TF1') || (key.fClassName===
'TF2'))
1301 return file.ReadFormulas(obj, user_call_back, -1);
1304 return JSROOT.AssertPrerequisites(
'tree',
function() {
1305 if (file.readTrees) {
1306 file.readTrees.forEach(
function(t) { JSROOT.extend(t, JSROOT.TreeMethods); })
1307 delete file.readTrees;
1309 JSROOT.CallBack(user_call_back, obj);
1312 JSROOT.CallBack(user_call_back, obj);
1319 TFile.prototype.ReadFormulas =
function(tf1, user_call_back, cnt) {
1322 while (++indx < this.fKeys.length) {
1323 if (this.fKeys[indx].fClassName ==
'TFormula')
break;
1326 if (indx >= this.fKeys.length)
1327 return JSROOT.CallBack(user_call_back, tf1);
1331 this.ReadObject(this.fKeys[indx].fName, this.fKeys[indx].fCycle,
function(formula) {
1332 tf1.addFormula(formula);
1333 file.ReadFormulas(tf1, user_call_back, indx);
1339 TFile.prototype.ExtractStreamerInfos =
function(buf) {
1343 buf.MapObject(1, lst);
1344 buf.ClassStreamer(lst,
'TList');
1346 lst._typename =
"TStreamerInfoList";
1348 this.fStreamerInfos = lst;
1350 if (typeof JSROOT.addStreamerInfos ===
'function')
1351 JSROOT.addStreamerInfos(lst);
1353 for (var k=0;k<lst.arr.length;++k) {
1354 var si = lst.arr[k];
1355 if (!si.fElements)
continue;
1356 for (var l=0;l<si.fElements.arr.length;++l) {
1357 var elem = si.fElements.arr[l];
1359 if (!elem.fTypeName || !elem.fType)
continue;
1361 var typ = elem.fType, typname = elem.fTypeName;
1364 if ((typ===JSROOT.IO.kStreamer) && (elem._typename==
"TStreamerSTL") && elem.fSTLtype && elem.fCtype && (elem.fCtype<20)) {
1365 var prefix = (JSROOT.IO.StlNames[elem.fSTLtype] ||
"undef") +
"<";
1366 if ((typname.indexOf(prefix)===0) && (typname[typname.length-1] ==
">")) {
1368 typname = typname.substr(prefix.length, typname.length-prefix.length-1).trim();
1370 if ((elem.fSTLtype === JSROOT.IO.kSTLmap) || (elem.fSTLtype === JSROOT.IO.kSTLmultimap))
1371 if (typname.indexOf(
",")>0) typname = typname.substr(0, typname.indexOf(
",")).trim();
1375 if (typ>=60)
continue;
1377 if ((typ>20) && (typname[typname.length-1]==
"*")) typname = typname.substr(0,typname.length-1);
1381 var kind = JSROOT.IO.GetTypeId(typname);
1382 if (kind === typ)
continue;
1384 if ((typ === JSROOT.IO.kBits) && (kind===JSROOT.IO.kUInt))
continue;
1385 if ((typ === JSROOT.IO.kCounter) && (kind===JSROOT.IO.kInt))
continue;
1387 if (typname && typ && (this.fBasicTypes[typname]!==typ)) {
1388 this.fBasicTypes[typname] = typ;
1389 if (!JSROOT.BatchMode) console.log(
'Extract basic data type', typ, typname);
1397 TFile.prototype.ReadKeys =
function(readkeys_callback) {
1402 this.ReadBuffer([0, 1024],
function(blob) {
1403 if (!blob)
return JSROOT.CallBack(readkeys_callback, null);
1405 var buf = JSROOT.CreateTBuffer(blob, 0, file);
1407 if (buf.substring(0, 4) !==
'root') {
1408 JSROOT.alert(
"NOT A ROOT FILE! " + file.fURL);
1409 return JSROOT.CallBack(readkeys_callback, null);
1413 file.fVersion = buf.ntou4();
1414 file.fBEGIN = buf.ntou4();
1415 if (file.fVersion < 1000000) {
1416 file.fEND = buf.ntou4();
1417 file.fSeekFree = buf.ntou4();
1418 file.fNbytesFree = buf.ntou4();
1420 file.fNbytesName = buf.ntou4();
1421 file.fUnits = buf.ntou1();
1422 file.fCompress = buf.ntou4();
1423 file.fSeekInfo = buf.ntou4();
1424 file.fNbytesInfo = buf.ntou4();
1426 file.fEND = buf.ntou8();
1427 file.fSeekFree = buf.ntou8();
1428 file.fNbytesFree = buf.ntou4();
1430 file.fNbytesName = buf.ntou4();
1431 file.fUnits = buf.ntou1();
1432 file.fCompress = buf.ntou4();
1433 file.fSeekInfo = buf.ntou8();
1434 file.fNbytesInfo = buf.ntou4();
1438 if (!file.fSeekInfo || !file.fNbytesInfo)
1439 return JSROOT.CallBack(readkeys_callback, null);
1442 if (!file.fNbytesName || file.fNbytesName > 100000) {
1443 JSROOT.console(
"Init : cannot read directory info of file " + file.fURL);
1444 return JSROOT.CallBack(readkeys_callback, null);
1448 var nbytes = file.fNbytesName + 22;
1453 if (file.fVersion >= 40000) nbytes += 12;
1456 file.ReadBuffer([file.fBEGIN, Math.max(300, nbytes)],
function(blob3) {
1457 if (!blob3)
return JSROOT.CallBack(readkeys_callback, null);
1459 var buf3 = JSROOT.CreateTBuffer(blob3, 0, file);
1462 file.fTitle = buf3.ReadTKey().fTitle;
1464 buf3.locate(file.fNbytesName);
1467 buf3.ClassStreamer(file,
'TDirectory');
1469 if (!file.fSeekKeys) {
1470 JSROOT.console(
"Empty keys list in " + file.fURL);
1471 return JSROOT.CallBack(readkeys_callback, null);
1475 file.ReadBuffer([file.fSeekKeys, file.fNbytesKeys, file.fSeekInfo, file.fNbytesInfo],
function(blobs) {
1477 if (!blobs)
return JSROOT.CallBack(readkeys_callback, null);
1479 var buf4 = JSROOT.CreateTBuffer(blobs[0], 0, file);
1482 var nkeys = buf4.ntoi4();
1483 for (var i = 0; i < nkeys; ++i)
1484 file.fKeys.push(buf4.ReadTKey());
1486 var buf5 = JSROOT.CreateTBuffer(blobs[1], 0, file),
1487 si_key = buf5.ReadTKey();
1488 if (!si_key)
return JSROOT.CallBack(readkeys_callback, null);
1490 file.fKeys.push(si_key);
1491 file.ReadObjBuffer(si_key,
function(blob6) {
1492 if (blob6) file.ExtractStreamerInfos(blob6);
1494 return JSROOT.CallBack(readkeys_callback, file);
1507 TFile.prototype.ReadDirectory =
function(dir_name, cycle, readdir_callback) {
1508 this.ReadObject(dir_name, cycle, readdir_callback,
true);
1511 JSROOT.IO.AddClassMethods =
function(clname, streamer) {
1514 if (streamer === null)
return streamer;
1516 var methods = JSROOT.getMethods(clname);
1518 if (methods !== null)
1519 for (var key in methods)
1520 if ((typeof methods[key] ===
'function') || (key.indexOf(
"_")==0))
1523 method: methods[key],
1524 func:
function(buf,obj) { obj[this.name] = this.method; }
1532 TFile.prototype.FindStreamerInfo =
function(clname, clversion, clchecksum) {
1533 if (this.fStreamerInfos)
1534 for (var i=0; i < this.fStreamerInfos.arr.length; ++i) {
1535 var si = this.fStreamerInfos.arr[i];
1538 if ((clchecksum !== undefined) && (si.fCheckSum === clchecksum))
return si;
1540 if (si.fName !== clname)
continue;
1543 if (clchecksum !== undefined)
continue;
1545 if ((clversion !== undefined) && (si.fClassVersion !== clversion))
continue;
1553 TFile.prototype.FindSinfoCheckum =
function(checksum) {
1554 if (!this.fStreamerInfos)
return null;
1556 var cache = this.fStreamerInfos.cache,
1557 arr = this.fStreamerInfos.arr;
1558 if (!cache) cache = this.fStreamerInfos.cache = {};
1560 var si = cache[checksum];
1561 if (si !== undefined)
return si;
1563 for (var i=0; i < arr.length; ++i) {
1565 if (si.fCheckSum === checksum) {
1566 cache[checksum] = si;
1571 cache[checksum] = null;
1575 JSROOT.IO.GetPairStreamer =
function(si, typname, file) {
1578 if (typname.indexOf(
"pair")!==0)
return null;
1580 si = file.FindStreamerInfo(typname);
1583 var p1 = typname.indexOf(
"<"), p2 = typname.lastIndexOf(
">");
1584 function GetNextName() {
1585 var res =
"", p = p1+1, cnt = 0;
1586 while ((p<p2) && (cnt>=0)) {
1587 switch (typname[p]) {
1588 case "<": cnt++;
break;
1589 case ",":
if (cnt===0) cnt--;
break;
1590 case ">": cnt--;
break;
1592 if (cnt>=0) res+=typname[p];
1598 si = { _typename:
'TStreamerInfo', fVersion: 1, fName: typname, fElements: JSROOT.Create(
"TList") };
1599 si.fElements.Add(JSROOT.IO.CreateStreamerElement(
"first", GetNextName(), file));
1600 si.fElements.Add(JSROOT.IO.CreateStreamerElement(
"second", GetNextName(), file));
1604 var streamer = file.GetStreamer(typname, null, si);
1606 if (!streamer)
return null;
1608 if (streamer.length!==2) {
1609 console.error(
'Streamer for pair class contains ', streamer.length,
'elements');
1614 for (var nn=0;nn<2;++nn)
1615 if (streamer[nn].readelem && !streamer[nn].pair_name) {
1616 streamer[nn].pair_name = (nn==0) ?
"first" :
"second";
1617 streamer[nn].func =
function(buf, obj) {
1618 obj[this.pair_name] = this.readelem(buf);
1625 JSROOT.IO.CreateMember =
function(element, file) {
1628 var member = { name: element.fName, type: element.fType,
1629 fArrayLength: element.fArrayLength,
1630 fArrayDim: element.fArrayDim,
1631 fMaxIndex: element.fMaxIndex };
1633 if (element.fTypeName ===
'BASE') {
1634 if (JSROOT.IO.GetArrayKind(member.name) > 0) {
1637 member.name =
'fArray';
1638 member.type = JSROOT.IO.kAny;
1641 member.type = JSROOT.IO.kBase;
1646 switch (member.type) {
1647 case JSROOT.IO.kBase:
1648 member.base = element.fBaseVersion;
1649 member.basename = element.fName;
1650 member.func =
function(buf, obj) { buf.ClassStreamer(obj, this.basename); };
1652 case JSROOT.IO.kShort:
1653 member.func =
function(buf,obj) { obj[this.name] = buf.ntoi2(); };
break;
1654 case JSROOT.IO.kInt:
1655 case JSROOT.IO.kCounter:
1656 member.func =
function(buf,obj) { obj[this.name] = buf.ntoi4(); };
break;
1657 case JSROOT.IO.kLong:
1658 case JSROOT.IO.kLong64:
1659 member.func =
function(buf,obj) { obj[this.name] = buf.ntoi8(); };
break;
1660 case JSROOT.IO.kDouble:
1661 member.func =
function(buf,obj) { obj[this.name] = buf.ntod(); };
break;
1662 case JSROOT.IO.kFloat:
1663 member.func =
function(buf,obj) { obj[this.name] = buf.ntof(); };
break;
1664 case JSROOT.IO.kLegacyChar:
1665 case JSROOT.IO.kUChar:
1666 member.func =
function(buf,obj) { obj[this.name] = buf.ntou1(); };
break;
1667 case JSROOT.IO.kUShort:
1668 member.func =
function(buf,obj) { obj[this.name] = buf.ntou2(); };
break;
1669 case JSROOT.IO.kBits:
1670 case JSROOT.IO.kUInt:
1671 member.func =
function(buf,obj) { obj[this.name] = buf.ntou4(); };
break;
1672 case JSROOT.IO.kULong64:
1673 case JSROOT.IO.kULong:
1674 member.func =
function(buf,obj) { obj[this.name] = buf.ntou8(); };
break;
1675 case JSROOT.IO.kBool:
1676 member.func =
function(buf,obj) { obj[this.name] = buf.ntou1() != 0; };
break;
1677 case JSROOT.IO.kOffsetL+JSROOT.IO.kBool:
1678 case JSROOT.IO.kOffsetL+JSROOT.IO.kInt:
1679 case JSROOT.IO.kOffsetL+JSROOT.IO.kCounter:
1680 case JSROOT.IO.kOffsetL+JSROOT.IO.kDouble:
1681 case JSROOT.IO.kOffsetL+JSROOT.IO.kUChar:
1682 case JSROOT.IO.kOffsetL+JSROOT.IO.kShort:
1683 case JSROOT.IO.kOffsetL+JSROOT.IO.kUShort:
1684 case JSROOT.IO.kOffsetL+JSROOT.IO.kBits:
1685 case JSROOT.IO.kOffsetL+JSROOT.IO.kUInt:
1686 case JSROOT.IO.kOffsetL+JSROOT.IO.kULong:
1687 case JSROOT.IO.kOffsetL+JSROOT.IO.kULong64:
1688 case JSROOT.IO.kOffsetL+JSROOT.IO.kLong:
1689 case JSROOT.IO.kOffsetL+JSROOT.IO.kLong64:
1690 case JSROOT.IO.kOffsetL+JSROOT.IO.kFloat:
1691 if (element.fArrayDim < 2) {
1692 member.arrlength = element.fArrayLength;
1693 member.func =
function(buf, obj) {
1694 obj[this.name] = buf.ReadFastArray(this.arrlength, this.type - JSROOT.IO.kOffsetL);
1697 member.arrlength = element.fMaxIndex[element.fArrayDim-1];
1698 member.minus1 =
true;
1699 member.func =
function(buf, obj) {
1700 obj[this.name] = buf.ReadNdimArray(
this,
function(buf,handle) {
1701 return buf.ReadFastArray(handle.arrlength, handle.type - JSROOT.IO.kOffsetL);
1706 case JSROOT.IO.kOffsetL+JSROOT.IO.kChar:
1707 if (element.fArrayDim < 2) {
1708 member.arrlength = element.fArrayLength;
1709 member.func =
function(buf, obj) {
1710 obj[this.name] = buf.ReadFastString(this.arrlength);
1713 member.minus1 =
true;
1714 member.arrlength = element.fMaxIndex[element.fArrayDim-1];
1715 member.func =
function(buf, obj) {
1716 obj[this.name] = buf.ReadNdimArray(
this,
function(buf,handle) {
1717 return buf.ReadFastString(handle.arrlength);
1722 case JSROOT.IO.kOffsetP+JSROOT.IO.kBool:
1723 case JSROOT.IO.kOffsetP+JSROOT.IO.kInt:
1724 case JSROOT.IO.kOffsetP+JSROOT.IO.kDouble:
1725 case JSROOT.IO.kOffsetP+JSROOT.IO.kUChar:
1726 case JSROOT.IO.kOffsetP+JSROOT.IO.kShort:
1727 case JSROOT.IO.kOffsetP+JSROOT.IO.kUShort:
1728 case JSROOT.IO.kOffsetP+JSROOT.IO.kBits:
1729 case JSROOT.IO.kOffsetP+JSROOT.IO.kUInt:
1730 case JSROOT.IO.kOffsetP+JSROOT.IO.kULong:
1731 case JSROOT.IO.kOffsetP+JSROOT.IO.kULong64:
1732 case JSROOT.IO.kOffsetP+JSROOT.IO.kLong:
1733 case JSROOT.IO.kOffsetP+JSROOT.IO.kLong64:
1734 case JSROOT.IO.kOffsetP+JSROOT.IO.kFloat:
1735 member.cntname = element.fCountName;
1736 member.func =
function(buf, obj) {
1737 if (buf.ntou1() === 1)
1738 obj[this.name] = buf.ReadFastArray(obj[
this.cntname],
this.type - JSROOT.IO.kOffsetP);
1740 obj[this.name] =
new Array();
1743 case JSROOT.IO.kOffsetP+JSROOT.IO.kChar:
1744 member.cntname = element.fCountName;
1745 member.func =
function(buf, obj) {
1746 if (buf.ntou1() === 1)
1747 obj[this.name] = buf.ReadFastString(obj[
this.cntname]);
1749 obj[this.name] = null;
1752 case JSROOT.IO.kDouble32:
1753 case JSROOT.IO.kOffsetL+JSROOT.IO.kDouble32:
1754 case JSROOT.IO.kOffsetP+JSROOT.IO.kDouble32:
1755 member.double32 =
true;
1756 case JSROOT.IO.kFloat16:
1757 case JSROOT.IO.kOffsetL+JSROOT.IO.kFloat16:
1758 case JSROOT.IO.kOffsetP+JSROOT.IO.kFloat16:
1759 if (element.fFactor!==0) {
1760 member.factor = 1./element.fFactor;
1761 member.min = element.fXmin;
1762 member.read =
function(buf) {
return buf.ntou4() * this.factor + this.min; };
1764 if ((element.fXmin===0) && member.double32) {
1765 member.read =
function(buf) {
return buf.ntof(); };
1767 member.nbits = Math.round(element.fXmin);
1768 if (member.nbits===0) member.nbits = 12;
1769 member.dv =
new DataView(
new ArrayBuffer(8), 0);
1770 member.read =
function(buf) {
1771 var theExp = buf.ntou1(), theMan = buf.ntou2();
1772 this.dv.setUint32(0, (theExp << 23) | ((theMan & ((1<<(this.nbits+1))-1)) << (23-this.nbits)));
1773 return ((1<<(this.nbits+1) & theMan) ? -1 : 1) * this.dv.getFloat32(0);
1777 member.readarr =
function(buf,len) {
1778 var arr = this.double32 ?
new Float64Array(len) : new Float32Array(len);
1779 for (var n=0;n<len;++n) arr[n] = this.read(buf);
1783 if (member.type < JSROOT.IO.kOffsetL) {
1784 member.func =
function(buf,obj) { obj[this.name] = this.read(buf); }
1786 if (member.type > JSROOT.IO.kOffsetP) {
1787 member.cntname = element.fCountName;
1788 member.func =
function(buf, obj) {
1789 if (buf.ntou1() === 1) {
1790 obj[this.name] = this.readarr(buf, obj[this.cntname]);
1792 obj[this.name] = null;
1796 if (element.fArrayDim < 2) {
1797 member.arrlength = element.fArrayLength;
1798 member.func =
function(buf, obj) { obj[this.name] = this.readarr(buf, this.arrlength); };
1800 member.arrlength = element.fMaxIndex[element.fArrayDim-1];
1801 member.minus1 =
true;
1802 member.func =
function(buf, obj) {
1803 obj[this.name] = buf.ReadNdimArray(
this,
function(buf,handle) {
return handle.readarr(buf, handle.arrlength); });
1808 case JSROOT.IO.kAnyP:
1809 case JSROOT.IO.kObjectP:
1810 member.func =
function(buf, obj) {
1811 obj[this.name] = buf.ReadNdimArray(
this,
function(buf) {
1812 return buf.ReadObjectAny();
1817 case JSROOT.IO.kAny:
1818 case JSROOT.IO.kAnyp:
1819 case JSROOT.IO.kObjectp:
1820 case JSROOT.IO.kObject:
1821 var classname = (element.fTypeName ===
'BASE') ? element.fName : element.fTypeName;
1822 if (classname[classname.length-1] ==
"*")
1823 classname = classname.substr(0, classname.length - 1);
1825 var arrkind = JSROOT.IO.GetArrayKind(classname);
1828 member.arrkind = arrkind;
1829 member.func =
function(buf, obj) {
1830 obj[this.name] = buf.ReadFastArray(buf.ntou4(), this.arrkind);
1833 if (arrkind === 0) {
1834 member.func =
function(buf,obj) { obj[this.name] = buf.ReadTString(); };
1836 member.classname = classname;
1838 if (element.fArrayLength>1) {
1839 member.func =
function(buf, obj) {
1840 obj[this.name] = buf.ReadNdimArray(
this,
function(buf, handle) {
1841 return buf.ClassStreamer({}, handle.classname);
1845 member.func =
function(buf, obj) {
1846 obj[this.name] = buf.ClassStreamer({}, this.classname);
1851 case JSROOT.IO.kOffsetL + JSROOT.IO.kObject:
1852 case JSROOT.IO.kOffsetL + JSROOT.IO.kAny:
1853 case JSROOT.IO.kOffsetL + JSROOT.IO.kAnyp:
1854 case JSROOT.IO.kOffsetL + JSROOT.IO.kObjectp:
1855 var classname = element.fTypeName;
1856 if (classname[classname.length-1] ==
"*")
1857 classname = classname.substr(0, classname.length - 1);
1859 member.arrkind = JSROOT.IO.GetArrayKind(classname);
1860 if (member.arrkind < 0) member.classname = classname;
1861 member.func =
function(buf, obj) {
1862 obj[this.name] = buf.ReadNdimArray(
this,
function(buf, handle) {
1863 if (handle.arrkind>0)
return buf.ReadFastArray(buf.ntou4(), handle.arrkind);
1864 if (handle.arrkind===0)
return buf.ReadTString();
1865 return buf.ClassStreamer({}, handle.classname);
1869 case JSROOT.IO.kChar:
1870 member.func =
function(buf,obj) { obj[this.name] = buf.ntoi1(); };
break;
1871 case JSROOT.IO.kCharStar:
1872 member.func =
function(buf,obj) {
1873 var len = buf.ntoi4();
1874 obj[this.name] = buf.substring(buf.o, buf.o + len);
1878 case JSROOT.IO.kTString:
1879 member.func =
function(buf,obj) { obj[this.name] = buf.ReadTString(); };
1881 case JSROOT.IO.kTObject:
1882 case JSROOT.IO.kTNamed:
1883 member.typename = element.fTypeName;
1884 member.func =
function(buf,obj) { obj[this.name] = buf.ClassStreamer({}, this.
typename); };
1886 case JSROOT.IO.kOffsetL+JSROOT.IO.kTString:
1887 case JSROOT.IO.kOffsetL+JSROOT.IO.kTObject:
1888 case JSROOT.IO.kOffsetL+JSROOT.IO.kTNamed:
1889 member.typename = element.fTypeName;
1890 member.func =
function(buf, obj) {
1891 var ver = buf.ReadVersion();
1892 obj[this.name] = buf.ReadNdimArray(
this,
function(buf, handle) {
1893 if (handle.typename ===
'TString')
return buf.ReadTString();
1894 return buf.ClassStreamer({}, handle.typename);
1896 buf.CheckBytecount(ver, this.
typename +
"[]");
1899 case JSROOT.IO.kStreamLoop:
1900 case JSROOT.IO.kOffsetL+JSROOT.IO.kStreamLoop:
1901 member.typename = element.fTypeName;
1902 member.cntname = element.fCountName;
1904 if (member.typename.lastIndexOf(
"**")>0) {
1905 member.typename = member.typename.substr(0, member.typename.lastIndexOf(
"**"));
1906 member.isptrptr =
true;
1908 member.typename = member.typename.substr(0, member.typename.lastIndexOf(
"*"));
1909 member.isptrptr =
false;
1912 if (member.isptrptr) {
1913 member.readitem =
function(buf) {
return buf.ReadObjectAny(); }
1915 member.arrkind = JSROOT.IO.GetArrayKind(member.typename);
1916 if (member.arrkind > 0)
1917 member.readitem =
function(buf) {
return buf.ReadFastArray(buf.ntou4(), this.arrkind); }
1918 else if (member.arrkind === 0)
1919 member.readitem =
function(buf) {
return buf.ReadTString(); }
1921 member.readitem =
function(buf) {
return buf.ClassStreamer({}, this.
typename); }
1924 if (member.readitem !== undefined) {
1925 member.read_loop =
function(buf,cnt) {
1926 return buf.ReadNdimArray(
this,
function(buf2,member2) {
1927 var itemarr =
new Array(cnt);
1928 for (var i = 0; i < cnt; ++i )
1929 itemarr[i] = member2.readitem(buf2);
1934 member.func =
function(buf,obj) {
1935 var ver = buf.ReadVersion();
1936 var res = this.read_loop(buf, obj[this.cntname]);
1937 if (!buf.CheckBytecount(ver,
this.typename)) res = null;
1938 obj[this.name] = res;
1940 member.branch_func =
function(buf,obj) {
1943 var ver = buf.ReadVersion(), sz0 = obj[this.stl_size], res =
new Array(sz0);
1945 for (var loop0=0;loop0<sz0;++loop0) {
1946 var cnt = obj[this.cntname][loop0];
1947 res[loop0] = this.read_loop(buf, cnt);
1949 if (!buf.CheckBytecount(ver,
this.typename)) res = null;
1950 obj[this.name] = res;
1953 member.objs_branch_func =
function(buf,obj) {
1958 var ver = buf.ReadVersion(), arr = obj[this.name0];
1960 for (var loop0=0;loop0<arr.length;++loop0) {
1961 var obj1 = this.
get(arr,loop0), cnt = obj1[this.cntname];
1962 obj1[this.name] = this.read_loop(buf, cnt);
1965 buf.CheckBytecount(ver, this.
typename);
1969 JSROOT.console(
'fail to provide function for ' + element.fName +
' (' + element.fTypeName +
') typ = ' + element.fType);
1970 member.func =
function(buf,obj) {
1971 var ver = buf.ReadVersion();
1972 buf.CheckBytecount(ver);
1973 obj[this.name] = ull;
1979 case JSROOT.IO.kStreamer:
1980 member.typename = element.fTypeName;
1982 var stl = (element.fSTLtype || 0) % 40;
1984 if ((element._typename ===
'TStreamerSTLstring') ||
1985 (member.typename ==
"string") || (member.typename ==
"string*")) {
1986 member.readelem =
function(buf) {
return buf.ReadTString(); };
1988 if ((stl === JSROOT.IO.kSTLvector) || (stl === JSROOT.IO.kSTLlist) ||
1989 (stl === JSROOT.IO.kSTLdeque) || (stl === JSROOT.IO.kSTLset) ||
1990 (stl === JSROOT.IO.kSTLmultiset)) {
1991 var p1 = member.typename.indexOf(
"<"),
1992 p2 = member.typename.lastIndexOf(
">");
1994 member.conttype = member.typename.substr(p1+1,p2-p1-1).trim();
1996 member.typeid = JSROOT.IO.GetTypeId(member.conttype);
1997 if ((member.typeid<0) && file.fBasicTypes[member.conttype]) {
1998 member.typeid = file.fBasicTypes[member.conttype];
1999 console.log(
'!!! Reuse basic type', member.conttype,
'from file streamer infos');
2003 if (element.fCtype && (element.fCtype < 20) && (element.fCtype !== member.typeid)) {
2004 console.warn(
'Contained type', member.conttype,
'not recognized as basic type', element.fCtype,
'FORCE');
2005 member.typeid = element.fCtype;
2008 if (member.typeid > 0) {
2009 member.readelem =
function(buf) {
2010 return buf.ReadFastArray(buf.ntoi4(), this.
typeid);
2013 member.isptr =
false;
2015 if (member.conttype.lastIndexOf(
"*") === member.conttype.length-1) {
2016 member.isptr =
true;
2017 member.conttype = member.conttype.substr(0,member.conttype.length-1);
2020 if (element.fCtype === JSROOT.IO.kObjectp) member.isptr =
true;
2022 member.arrkind = JSROOT.IO.GetArrayKind(member.conttype);
2024 member.readelem = JSROOT.IO.ReadVectorElement;
2026 if (!member.isptr && (member.arrkind<0)) {
2028 var subelem = JSROOT.IO.CreateStreamerElement(
"temp", member.conttype);
2030 if (subelem.fType === JSROOT.IO.kStreamer) {
2031 subelem.$fictional =
true;
2032 member.submember = JSROOT.IO.CreateMember(subelem, file);
2037 if ((stl === JSROOT.IO.kSTLmap) || (stl === JSROOT.IO.kSTLmultimap)) {
2039 var p1 = member.typename.indexOf(
"<"),
2040 p2 = member.typename.lastIndexOf(
">");
2042 member.pairtype =
"pair<" + member.typename.substr(p1+1,p2-p1-1) +
">";
2046 member.si = file.FindStreamerInfo(member.pairtype);
2048 member.streamer = JSROOT.IO.GetPairStreamer(member.si, member.pairtype, file);
2050 if (!member.streamer || (member.streamer.length!==2)) {
2051 JSROOT.console(
'Fail to build streamer for pair ' + member.pairtype);
2052 delete member.streamer;
2055 if (member.streamer) member.readelem = JSROOT.IO.ReadMapElement;
2057 if (stl === JSROOT.IO.kSTLbitset) {
2058 member.readelem =
function(buf,obj) {
2059 return buf.ReadFastArray(buf.ntou4(), JSROOT.IO.kBool);
2063 if (!member.readelem) {
2064 JSROOT.console(
'failed to create streamer for element ' + member.typename +
' ' + member.name +
' element ' + element._typename +
' STL type ' + element.fSTLtype);
2065 member.func =
function(buf,obj) {
2066 var ver = buf.ReadVersion();
2067 buf.CheckBytecount(ver);
2068 obj[this.name] = null;
2071 if (!element.$fictional) {
2073 member.read_version =
function(buf, cnt) {
2074 if (cnt===0)
return null;
2075 var o = buf.o, ver = buf.ReadVersion();
2076 this.member_wise = ((ver.val & JSROOT.IO.kStreamedMemberWise) !== 0);
2077 this.stl_version = undefined;
2078 if (this.member_wise) {
2079 this.stl_version = { val: buf.ntoi2() };
2080 if (this.stl_version.val<=0) this.stl_version.checksum = buf.ntou4();
2085 member.func =
function(buf,obj) {
2086 var ver = this.read_version(buf);
2088 var res = buf.ReadNdimArray(
this,
function(buf2,member2) {
return member2.readelem(buf2); });
2090 if (!buf.CheckBytecount(ver,
this.typename)) res = null;
2091 obj[this.name] = res;
2094 member.branch_func =
function(buf,obj) {
2096 var cnt = obj[this.stl_size], arr =
new Array(cnt);
2098 var ver = this.read_version(buf, cnt);
2100 for (var n=0;n<cnt;++n)
2101 arr[n] = buf.ReadNdimArray(
this,
function(buf2,member2) {
return member2.readelem(buf2); });
2103 if (ver) buf.CheckBytecount(ver,
"branch " + this.
typename);
2105 obj[this.name] = arr;
2107 member.split_func =
function(buf, arr, n) {
2109 var ver = this.read_version(buf);
2110 for (var i=0;i<n;++i)
2111 arr[i][this.name] = buf.ReadNdimArray(
this,
function(buf2,member2) {
return member2.readelem(buf2); });
2112 buf.CheckBytecount(ver, this.
typename);
2114 member.objs_branch_func =
function(buf,obj) {
2119 var arr = obj[this.name0];
2121 var ver = this.read_version(buf, arr.length);
2123 for (var n=0;n<arr.length;++n) {
2124 var obj1 = this.
get(arr,n);
2125 obj1[this.name] = buf.ReadNdimArray(
this,
function(buf2,member2) {
return member2.readelem(buf2); });
2128 if (ver) buf.CheckBytecount(ver,
"branch " + this.
typename);
2134 JSROOT.console(
'fail to provide function for ' + element.fName +
' (' + element.fTypeName +
') typ = ' + element.fType);
2136 member.func =
function(buf,obj) {};
2145 TFile.prototype.GetStreamer =
function(clname, ver, s_i) {
2148 if (clname ==
'TQObject' || clname ==
"TBasket")
return null;
2150 var streamer, fullname = clname;
2153 fullname += (ver.checksum ? (
"$chksum" + ver.checksum) : (
"$ver" + ver.val));
2154 streamer = this.fStreamers[fullname];
2155 if (streamer !== undefined)
return streamer;
2158 var custom = JSROOT.IO.CustomStreamers[clname];
2161 if (typeof custom ===
'string')
2162 return this.GetStreamer(custom, ver, s_i);
2165 if (typeof custom ===
'function') {
2166 streamer = [{
typename: clname, func: custom }];
2167 return JSROOT.IO.AddClassMethods(clname, streamer);
2172 if (typeof custom ===
'object') {
2173 if (!custom.name && !custom.func)
return custom;
2174 streamer.push(custom);
2178 if (!s_i) s_i = this.FindStreamerInfo(clname, ver.val, ver.checksum);
2181 delete this.fStreamers[fullname];
2183 console.warn(
"Not found streamer for", clname,
"ver", ver.val,
"checksum", ver.checksum, fullname);
2190 for (var j=0; j < s_i.fElements.arr.length; ++j)
2191 streamer.push(JSROOT.IO.CreateMember(s_i.fElements.arr[j],
this));
2193 this.fStreamers[fullname] = streamer;
2195 return JSROOT.IO.AddClassMethods(clname, streamer);
2200 TFile.prototype.GetSplittedStreamer =
function(streamer, tgt) {
2201 if (!streamer)
return tgt;
2205 for (var n=0;n<streamer.length;++n) {
2206 var elem = streamer[n];
2208 if (elem.base === undefined) {
2213 if (elem.basename ==
'TObject') {
2214 tgt.push({ func:
function(buf,obj) {
2216 obj.fUniqueID = buf.ntou4();
2217 obj.fBits = buf.ntou4();
2218 if (obj.fBits & JSROOT.IO.kIsReferenced) buf.ntou2();
2223 var ver = { val: elem.base };
2225 if (ver.val === 4294967295) {
2230 var parent = this.GetStreamer(elem.basename, ver);
2231 if (parent) this.GetSplittedStreamer(parent, tgt);
2237 TFile.prototype.Delete =
function() {
2238 this.fDirectories = null;
2240 this.fStreamers = null;
2242 this.fNbytesInfo = 0;
2243 this.fTagOffset = 0;
2248 function TLocalFile(file, newfile_callback) {
2249 TFile.call(
this, null);
2250 this.fUseStampPar =
false;
2251 this.fLocalFile = file;
2252 this.fEND = file.size;
2253 this.fFullURL = file.name;
2254 this.fURL = file.name;
2255 this.fFileName = file.name;
2256 this.ReadKeys(newfile_callback);
2260 TLocalFile.prototype = Object.create(TFile.prototype);
2262 TLocalFile.prototype.ReadBuffer =
function(place, result_callback, filename, progress_callback) {
2265 throw new Error(
"Cannot access other local file "+filename)
2267 var reader = new FileReader(), cnt = 0, blobs = [], file = this.fLocalFile;
2269 reader.onload = function(evnt) {
2270 var res =
new DataView(evnt.target.result);
2271 if (place.length===2)
return result_callback(res);
2275 if (cnt >= place.length)
return result_callback(blobs);
2276 reader.readAsArrayBuffer(file.slice(place[cnt], place[cnt]+place[cnt+1]));
2279 reader.readAsArrayBuffer(file.slice(place[0], place[0]+place[1]));
2284 function TNodejsFile(filename, newfile_callback) {
2285 TFile.call(
this, null);
2286 this.fUseStampPar =
false;
2288 this.fFullURL = filename;
2289 this.fURL = filename;
2290 this.fFileName = filename;
2294 pthis.fs = require(
'fs');
2296 pthis.fs.open(filename,
'r',
function(status, fd) {
2298 console.log(status.message);
2299 return JSROOT.CallBack(newfile_callback, null);
2301 var stats = pthis.fs.fstatSync(fd);
2303 pthis.fEND = stats.size;
2309 pthis.ReadKeys(newfile_callback);
2319 TNodejsFile.prototype = Object.create(TFile.prototype);
2321 TNodejsFile.prototype.ReadBuffer =
function(place, result_callback, filename, progress_callback) {
2324 throw new Error(
"Cannot access other local file "+filename);
2326 if (!this.fs || !this.fd)
2327 throw new Error(
"File is not opened " + this.fFileName);
2329 var cnt = 0, blobs = [], file =
this;
2331 function readfunc(err, bytesRead, buf) {
2333 var res =
new DataView(buf.buffer, buf.byteOffset, place[cnt+1]);
2334 if (place.length===2)
return result_callback(res);
2338 if (cnt >= place.length)
return result_callback(blobs);
2339 file.fs.read(file.fd,
new Buffer(place[cnt+1]), 0, place[cnt+1], place[cnt], readfunc);
2342 file.fs.read(file.fd,
new Buffer(place[1]), 0, place[1], place[0], readfunc);
2348 JSROOT.IO.ProduceCustomStreamers =
function() {
2349 var cs = JSROOT.IO.CustomStreamers;
2351 cs[
'TObject'] = cs[
'TMethodCall'] =
function(buf,obj) {
2352 obj.fUniqueID = buf.ntou4();
2353 obj.fBits = buf.ntou4();
2354 if (obj.fBits & JSROOT.IO.kIsReferenced) buf.ntou2();
2358 { basename:
'TObject', base: 1, func:
function(buf,obj) {
2359 if (!obj._typename) obj._typename =
'TNamed';
2360 buf.ClassStreamer(obj,
"TObject"); }
2362 { name:
'fName', func:
function(buf,obj) { obj.fName = buf.ReadTString(); } },
2363 { name:
'fTitle', func:
function(buf,obj) { obj.fTitle = buf.ReadTString(); } }
2365 JSROOT.IO.AddClassMethods(
'TNamed', cs[
'TNamed']);
2367 cs[
'TObjString'] = [
2368 { basename:
'TObject', base: 1, func:
function(buf,obj) {
2369 if (!obj._typename) obj._typename =
'TObjString';
2370 buf.ClassStreamer(obj,
"TObject"); }
2372 { name:
'fString', func:
function(buf, obj) { obj.fString = buf.ReadTString(); } }
2375 JSROOT.IO.AddClassMethods(
'TObjString', cs[
'TObjString']);
2377 cs[
'TList'] = cs[
'THashList'] =
function(buf, obj) {
2379 if (!obj._typename) obj._typename = this.
typename;
2380 obj.$kind =
"TList";
2381 if (buf.last_read_version > 3) {
2382 buf.ClassStreamer(obj,
"TObject");
2383 obj.name = buf.ReadTString();
2384 var nobjects = buf.ntou4(), i = 0;
2385 obj.arr =
new Array(nobjects);
2386 obj.opt =
new Array(nobjects);
2387 for (; i<nobjects; ++i) {
2388 obj.arr[i] = buf.ReadObjectAny();
2389 obj.opt[i] = buf.ReadTString();
2398 cs[
'TClonesArray'] =
function(buf, list) {
2399 if (!list._typename) list._typename =
"TClonesArray";
2400 list.$kind =
"TClonesArray";
2402 var ver = buf.last_read_version;
2403 if (ver > 2) buf.ClassStreamer(list,
"TObject");
2404 if (ver > 1) list.name = buf.ReadTString();
2405 var classv = buf.ReadTString(), clv = 0,
2406 pos = classv.lastIndexOf(
";");
2409 clv = parseInt(classv.substr(pos+1));
2410 classv = classv.substr(0, pos);
2413 var nobjects = buf.ntou4();
2414 if (nobjects < 0) nobjects = -nobjects;
2416 list.arr =
new Array(nobjects);
2417 list.fLast = nobjects-1;
2418 list.fLowerBound = buf.ntou4();
2420 var streamer = buf.fFile.GetStreamer(classv, { val: clv });
2421 streamer = buf.fFile.GetSplittedStreamer(streamer);
2424 console.log(
'Cannot get member-wise streamer for', classv, clv);
2427 for (var n=0;n<nobjects;++n)
2428 list.arr[n] = { _typename: classv };
2431 for (var k=0;k<streamer.length;++k)
2432 for (var n=0;n<nobjects;++n)
2433 streamer[k].func(buf, list.arr[n]);
2437 cs[
'TMap'] =
function(buf, map) {
2438 if (!map._typename) map._typename =
"TMap";
2440 map.arr =
new Array();
2441 var ver = buf.last_read_version;
2442 if (ver > 2) buf.ClassStreamer(map,
"TObject");
2443 if (ver > 1) map.name = buf.ReadTString();
2445 var nobjects = buf.ntou4();
2447 for (var n=0;n<nobjects;++n) {
2448 var obj = { _typename:
"TPair" };
2449 obj.first = buf.ReadObjectAny();
2450 obj.second = buf.ReadObjectAny();
2451 if (obj.first) map.arr.push(obj);
2455 cs[
'TTreeIndex'] =
function(buf, obj) {
2456 var ver = buf.last_read_version;
2457 obj._typename =
"TTreeIndex";
2458 buf.ClassStreamer(obj,
"TVirtualIndex");
2459 obj.fMajorName = buf.ReadTString();
2460 obj.fMinorName = buf.ReadTString();
2461 obj.fN = buf.ntoi8();
2462 obj.fIndexValues = buf.ReadFastArray(obj.fN, JSROOT.IO.kLong64);
2463 if (ver>1) obj.fIndexValuesMinor = buf.ReadFastArray(obj.fN, JSROOT.IO.kLong64);
2464 obj.fIndex = buf.ReadFastArray(obj.fN, JSROOT.IO.kLong64);
2467 cs[
'TRefArray'] =
function(buf, obj) {
2468 obj._typename =
"TRefArray";
2469 buf.ClassStreamer(obj,
"TObject");
2470 obj.name = buf.ReadTString();
2471 var nobj = buf.ntoi4();
2473 obj.fLowerBound = buf.ntoi4();
2474 var pidf = buf.ntou2();
2475 obj.fUIDs = buf.ReadFastArray(nobj, JSROOT.IO.kUInt);
2478 cs[
'TCanvas'] =
function(buf, obj) {
2479 obj._typename =
"TCanvas";
2480 buf.ClassStreamer(obj,
"TPad");
2481 obj.fDISPLAY = buf.ReadTString();
2482 obj.fDoubleBuffer = buf.ntoi4();
2483 obj.fRetained = (buf.ntou1() !== 0);
2484 obj.fXsizeUser = buf.ntoi4();
2485 obj.fYsizeUser = buf.ntoi4();
2486 obj.fXsizeReal = buf.ntoi4();
2487 obj.fYsizeReal = buf.ntoi4();
2488 obj.fWindowTopX = buf.ntoi4();
2489 obj.fWindowTopY = buf.ntoi4();
2490 obj.fWindowWidth = buf.ntoi4();
2491 obj.fWindowHeight = buf.ntoi4();
2492 obj.fCw = buf.ntou4();
2493 obj.fCh = buf.ntou4();
2494 obj.fCatt = buf.ClassStreamer({},
"TAttCanvas");
2497 obj.fHighLightColor = buf.ntoi2();
2498 obj.fBatch = (buf.ntou1() !== 0);
2504 cs[
'TObjArray'] =
function(buf, list) {
2505 if (!list._typename) list._typename =
"TObjArray";
2506 list.$kind =
"TObjArray";
2508 var ver = buf.last_read_version;
2510 buf.ClassStreamer(list,
"TObject");
2512 list.name = buf.ReadTString();
2513 var nobjects = buf.ntou4(), i = 0;
2514 list.arr =
new Array(nobjects);
2515 list.fLast = nobjects-1;
2516 list.fLowerBound = buf.ntou4();
2517 while (i < nobjects)
2518 list.arr[i++] = buf.ReadObjectAny();
2521 cs[
'TPolyMarker3D'] =
function(buf, marker) {
2522 var ver = buf.last_read_version;
2523 buf.ClassStreamer(marker,
"TObject");
2524 buf.ClassStreamer(marker,
"TAttMarker");
2525 marker.fN = buf.ntoi4();
2526 marker.fP = buf.ReadFastArray(marker.fN*3, JSROOT.IO.kFloat);
2527 marker.fOption = buf.ReadTString();
2528 marker.fName = (ver > 1) ? buf.ReadTString() :
"TPolyMarker3D";
2531 cs[
'TPolyLine3D'] =
function(buf, obj) {
2532 buf.ClassStreamer(obj,
"TObject");
2533 buf.ClassStreamer(obj,
"TAttLine");
2534 obj.fN = buf.ntoi4();
2535 obj.fP = buf.ReadFastArray(obj.fN*3, JSROOT.IO.kFloat);
2536 obj.fOption = buf.ReadTString();
2539 cs[
'TStreamerInfo'] =
function(buf, obj) {
2541 buf.ClassStreamer(obj,
"TNamed");
2542 obj.fCheckSum = buf.ntou4();
2543 obj.fClassVersion = buf.ntou4();
2544 obj.fElements = buf.ReadObjectAny();
2547 cs[
'TStreamerElement'] =
function(buf, element) {
2550 var ver = buf.last_read_version;
2551 buf.ClassStreamer(element,
"TNamed");
2552 element.fType = buf.ntou4();
2553 element.fSize = buf.ntou4();
2554 element.fArrayLength = buf.ntou4();
2555 element.fArrayDim = buf.ntou4();
2556 element.fMaxIndex = buf.ReadFastArray((ver == 1) ? buf.ntou4() : 5, JSROOT.IO.kUInt);
2557 element.fTypeName = buf.ReadTString();
2559 if ((element.fType === JSROOT.IO.kUChar) && ((element.fTypeName ==
"Bool_t") || (element.fTypeName ==
"bool")))
2560 element.fType = JSROOT.IO.kBool;
2562 element.fXmin = element.fXmax = element.fFactor = 0;
2564 element.fXmin = buf.ntod();
2565 element.fXmax = buf.ntod();
2566 element.fFactor = buf.ntod();
2568 if ((ver > 3) && (element.fBits & JSROOT.BIT(6))) {
2570 var p1 = element.fTitle.indexOf(
"[");
2571 if ((p1>=0) && (element.fType>JSROOT.IO.kOffsetP)) p1 = element.fTitle.indexOf(
"[", p1+1);
2572 var p2 = element.fTitle.indexOf(
"]", p1+1);
2574 if ((p1>=0) && (p2>=p1+2)) {
2575 var arr = JSROOT.ParseAsArray(element.fTitle.substr(p1, p2-p1+1)), nbits = 32;
2577 if (arr.length===3) nbits = parseInt(arr[2]);
2578 if (isNaN(nbits) || (nbits<2) || (nbits>32)) nbits = 32;
2580 function parse_range(val) {
2582 if (val.indexOf(
"pi")<0)
return parseFloat(val);
2585 if (val[0] ==
"-") { sign = -1; val = val.substr(1); }
2589 case "twopi":
return sign*2*Math.PI;
2590 case "pi/2":
return sign*Math.PI/2;
2591 case "pi/4":
return sign*Math.PI/4;
2593 return sign*Math.PI;
2596 element.fXmin = parse_range(arr[0]);
2597 element.fXmax = parse_range(arr[1]);
2599 var bigint = (nbits < 32) ? (1<<nbits) : 0xffffffff;
2600 if (element.fXmin < element.fXmax) element.fFactor = bigint/(element.fXmax - element.fXmin);
2601 else if (nbits<15) element.fXmin = nbits;
2606 cs[
'TStreamerBase'] =
function(buf, elem) {
2607 var ver = buf.last_read_version;
2608 buf.ClassStreamer(elem,
"TStreamerElement");
2609 if (ver > 2) elem.fBaseVersion = buf.ntou4();
2612 cs[
'TStreamerBasicPointer'] = cs[
'TStreamerLoop'] =
function(buf,elem) {
2613 if (buf.last_read_version > 1) {
2614 buf.ClassStreamer(elem,
"TStreamerElement");
2615 elem.fCountVersion = buf.ntou4();
2616 elem.fCountName = buf.ReadTString();
2617 elem.fCountClass = buf.ReadTString();
2621 cs[
'TStreamerSTL'] =
function(buf, elem) {
2622 buf.ClassStreamer(elem,
"TStreamerElement");
2623 elem.fSTLtype = buf.ntou4();
2624 elem.fCtype = buf.ntou4();
2626 if ((elem.fSTLtype === JSROOT.IO.kSTLmultimap) &&
2627 ((elem.fTypeName.indexOf(
"std::set")===0) ||
2628 (elem.fTypeName.indexOf(
"set")==0))) elem.fSTLtype = JSROOT.IO.kSTLset;
2630 if ((elem.fSTLtype === JSROOT.IO.kSTLset) &&
2631 ((elem.fTypeName.indexOf(
"std::multimap")===0) ||
2632 (elem.fTypeName.indexOf(
"multimap")===0))) elem.fSTLtype = JSROOT.IO.kSTLmultimap;
2635 cs[
'TStreamerSTLstring'] =
function(buf, elem) {
2636 if (buf.last_read_version > 0)
2637 buf.ClassStreamer(elem,
"TStreamerSTL");
2640 cs[
'TStreamerObject'] = cs[
'TStreamerBasicType'] = cs[
'TStreamerObjectAny'] =
2641 cs[
'TStreamerString'] = cs[
'TStreamerObjectPointer'] =
function(buf, elem) {
2642 if (buf.last_read_version > 1)
2643 buf.ClassStreamer(elem,
"TStreamerElement");
2646 cs[
'TStreamerObjectAnyPointer'] =
function(buf, elem) {
2647 if (buf.last_read_version > 0)
2648 buf.ClassStreamer(elem,
"TStreamerElement");
2653 func:
function(buf,obj) { obj.$kind =
"TTree"; obj.$file = buf.fFile; buf.fFile.AddReadTree(obj); }
2656 cs[
'TVirtualPerfStats'] =
"TObject";
2658 cs[
'RooRealVar'] =
function(buf,obj) {
2659 var v = buf.last_read_version;
2660 buf.ClassStreamer(obj,
"RooAbsRealLValue");
2661 if (v==1) { buf.ntod(); buf.ntod(); buf.ntoi4(); }
2662 obj._error = buf.ntod();
2663 obj._asymErrLo = buf.ntod();
2664 obj._asymErrHi = buf.ntod();
2665 if (v>=2) obj._binning = buf.ReadObjectAny();
2666 if (v==3) obj._sharedProp = buf.ReadObjectAny();
2667 if (v>=4) obj._sharedProp = buf.ClassStreamer({},
"RooRealVarSharedProperties");
2670 cs[
'RooAbsBinning'] =
function(buf,obj) {
2671 buf.ClassStreamer(obj, (buf.last_read_version==1) ?
"TObject" :
"TNamed");
2672 buf.ClassStreamer(obj,
"RooPrintable");
2675 cs[
'RooCategory'] =
function(buf,obj) {
2676 var v = buf.last_read_version;
2677 buf.ClassStreamer(obj,
"RooAbsCategoryLValue");
2678 obj._sharedProp = (v===1) ? buf.ReadObjectAny() : buf.ClassStreamer({},
"RooCategorySharedProperties");
2681 cs[
'RooWorkspace::CodeRepo'] =
function(buf,obj) {
2682 var sz = (buf.last_read_version == 2) ? 3 : 2;
2683 for (var i=0;i<sz;++i) {
2684 var cnt = buf.ntoi4() * ((i==0) ? 4 : 3);
2685 while (cnt--) buf.ReadTString();
2689 cs[
'RooLinkedList'] =
function(buf,obj) {
2690 var v = buf.last_read_version;
2691 buf.ClassStreamer(obj,
"TObject");
2692 var size = buf.ntoi4();
2693 obj.arr = JSROOT.Create(
"TList");
2695 obj.arr.Add(buf.ReadObjectAny());
2696 if (v>1) obj._name = buf.ReadTString();
2699 cs[
'TASImage'] =
function(buf,obj) {
2700 if ((buf.last_read_version==1) && (buf.fFile.fVersion>0) && (buf.fFile.fVersion<50000)) {
2701 return console.warn(
"old TASImage version - not yet supported");
2704 buf.ClassStreamer(obj,
"TNamed");
2706 if (buf.ntou1() != 0) {
2707 var size = buf.ntoi4();
2708 obj.fPngBuf = buf.ReadFastArray(size, JSROOT.IO.kUChar);
2710 buf.ClassStreamer(obj,
"TAttImage");
2711 obj.fWidth = buf.ntoi4();
2712 obj.fHeight = buf.ntoi4();
2713 obj.fImgBuf = buf.ReadFastArray(obj.fWidth*obj.fHeight, JSROOT.IO.kDouble);
2717 cs[
'TMaterial'] =
function(buf,obj) {
2718 var v = buf.last_read_version;
2719 buf.ClassStreamer(obj,
"TNamed");
2720 obj.fNumber = buf.ntoi4();
2721 obj.fA = buf.ntof();
2722 obj.fZ = buf.ntof();
2723 obj.fDensity = buf.ntof();
2725 buf.ClassStreamer(obj,
"TAttFill");
2726 obj.fRadLength = buf.ntof();
2727 obj.fInterLength = buf.ntof();
2729 obj.fRadLength = obj.fInterLength = 0;
2733 cs[
'TMixture'] =
function(buf,obj) {
2734 buf.ClassStreamer(obj,
"TMaterial");
2735 obj.fNmixt = buf.ntoi4();
2736 obj.fAmixt = buf.ReadFastArray(buf.ntoi4(), JSROOT.IO.kFloat);
2737 obj.fZmixt = buf.ReadFastArray(buf.ntoi4(), JSROOT.IO.kFloat);
2738 obj.fWmixt = buf.ReadFastArray(buf.ntoi4(), JSROOT.IO.kFloat);
2743 var ds = JSROOT.IO.DirectStreamers;
2745 ds[
'TQObject'] = ds[
'TGraphStruct'] = ds[
'TGraphNode'] = ds[
'TGraphEdge'] =
function(buf,obj) {
2749 ds[
'TDatime'] =
function(buf,obj) {
2750 obj.fDatime = buf.ntou4();
2764 ds[
'TKey'] =
function(buf,key) {
2765 key.fNbytes = buf.ntoi4();
2766 key.fVersion = buf.ntoi2();
2767 key.fObjlen = buf.ntou4();
2768 key.fDatime = buf.ClassStreamer({},
'TDatime');
2769 key.fKeylen = buf.ntou2();
2770 key.fCycle = buf.ntou2();
2771 if (key.fVersion > 1000) {
2772 key.fSeekKey = buf.ntou8();
2775 key.fSeekKey = buf.ntou4();
2778 key.fClassName = buf.ReadTString();
2779 key.fName = buf.ReadTString();
2780 key.fTitle = buf.ReadTString();
2783 ds[
'TDirectory'] =
function(buf, dir) {
2784 var version = buf.ntou2();
2785 dir.fDatimeC = buf.ClassStreamer({},
'TDatime');
2786 dir.fDatimeM = buf.ClassStreamer({},
'TDatime');
2787 dir.fNbytesKeys = buf.ntou4();
2788 dir.fNbytesName = buf.ntou4();
2789 dir.fSeekDir = (version > 1000) ? buf.ntou8() : buf.ntou4();
2790 dir.fSeekParent = (version > 1000) ? buf.ntou8() : buf.ntou4();
2791 dir.fSeekKeys = (version > 1000) ? buf.ntou8() : buf.ntou4();
2795 ds[
'TBasket'] =
function(buf,obj) {
2796 buf.ClassStreamer(obj,
'TKey');
2797 var ver = buf.ReadVersion();
2798 obj.fBufferSize = buf.ntoi4();
2799 obj.fNevBufSize = buf.ntoi4();
2800 obj.fNevBuf = buf.ntoi4();
2801 obj.fLast = buf.ntoi4();
2802 if (obj.fLast > obj.fBufferSize) obj.fBufferSize = obj.fLast;
2803 var flag = buf.ntoi1();
2805 if (flag===0)
return;
2807 if ((flag % 10) != 2) {
2809 obj.fEntryOffset = buf.ReadFastArray(buf.ntoi4(), JSROOT.IO.kInt);
2810 if ((20<flag) && (flag<40))
2811 for(var i=0, kDisplacementMask = 0xFF000000; i<obj.fNevBuf; ++i)
2812 obj.fEntryOffset[i] &= ~kDisplacementMask;
2816 obj.fDisplacement = buf.ReadFastArray(buf.ntoi4(), JSROOT.IO.kInt);
2819 if ((flag === 1) || (flag > 10)) {
2821 var sz = (ver.val <= 1) ? buf.ntoi4() : obj.fLast;
2823 if (sz > obj.fKeylen) {
2825 var blob = buf.extract([buf.o + obj.fKeylen, sz - obj.fKeylen]);
2827 obj.fBufferRef = JSROOT.CreateTBuffer(blob, 0, buf.fFile, sz - obj.fKeylen);
2828 obj.fBufferRef.fTagOffset = obj.fKeylen;
2835 ds[
'TRef'] =
function(buf,obj) {
2836 buf.ClassStreamer(obj,
"TObject");
2837 if (obj.fBits & JSROOT.IO.kHasUUID)
2838 obj.fUUID = buf.ReadTString();
2840 obj.fPID = buf.ntou2();
2843 ds[
'TMatrixTSym<float>'] =
function(buf,obj) {
2844 buf.ClassStreamer(obj,
"TMatrixTBase<float>");
2845 obj.fElements =
new Float32Array(obj.fNelems);
2846 var arr = buf.ReadFastArray((obj.fNrows * (obj.fNcols + 1))/2, JSROOT.IO.kFloat), cnt = 0;
2847 for (var i=0;i<obj.fNrows;++i)
2848 for (var j=i;j<obj.fNcols;++j)
2849 obj.fElements[j*obj.fNcols+i] = obj.fElements[i*obj.fNcols+j] = arr[cnt++];
2852 ds[
'TMatrixTSym<double>'] =
function(buf,obj) {
2853 buf.ClassStreamer(obj,
"TMatrixTBase<double>");
2854 obj.fElements =
new Float64Array(obj.fNelems);
2855 var arr = buf.ReadFastArray((obj.fNrows * (obj.fNcols + 1))/2, JSROOT.IO.kDouble), cnt = 0;
2856 for (var i=0;i<obj.fNrows;++i)
2857 for (var j=i;j<obj.fNcols;++j)
2858 obj.fElements[j*obj.fNcols+i] = obj.fElements[i*obj.fNcols+j] = arr[cnt++];
2863 JSROOT.IO.CreateStreamerElement =
function(name,
typename, file) {
2866 var elem = { _typename:
'TStreamerElement', fName: name, fTypeName:
typename,
2867 fType: 0, fSize: 0, fArrayLength: 0, fArrayDim: 0, fMaxIndex: [0,0,0,0,0],
2868 fXmin: 0, fXmax: 0, fFactor: 0 };
2870 if (typeof
typename ===
"string") {
2871 elem.fType = JSROOT.IO.GetTypeId(
typename);
2872 if ((elem.fType<0) && file && file.fBasicTypes[
typename])
2873 elem.fType = file.fBasicTypes[
typename];
2875 elem.fType =
typename;
2876 typename = elem.fTypeName = JSROOT.IO.TypeNames[elem.fType] ||
"int";
2879 if (elem.fType > 0)
return elem;
2882 var stltype = JSROOT.IO.kNotSTL, pos =
typename.indexOf(
"<");
2883 if ((pos>0) && (
typename.indexOf(
">") > pos+2))
2884 for (var stl=1;stl<JSROOT.IO.StlNames.length;++stl)
2885 if (
typename.substr(0, pos) === JSROOT.IO.StlNames[stl]) {
2886 stltype = stl;
break;
2889 if (stltype !== JSROOT.IO.kNotSTL) {
2890 elem._typename =
'TStreamerSTL';
2891 elem.fType = JSROOT.IO.kStreamer;
2892 elem.fSTLtype = stltype;
2899 if (
typename.lastIndexOf(
"*") ===
typename.length-1) {
2901 elem.fTypeName =
typename =
typename.substr(0,
typename.length-1);
2904 var arrkind = JSROOT.IO.GetArrayKind(
typename);
2907 elem.fType = JSROOT.IO.kTString;
2911 elem.fType = isptr ? JSROOT.IO.kAnyP : JSROOT.IO.kAny;
2916 JSROOT.IO.ReadVectorElement =
function(buf) {
2918 if (this.member_wise) {
2920 var n = buf.ntou4(), streamer = null, ver = this.stl_version;
2922 if (n===0)
return [];
2925 throw new Error(
'member-wise streaming of ' + this.conttype +
" num " + n +
' member ' + this.name);
2929 if ((ver.val ===
this.member_ver) && (ver.checksum ===
this.member_checksum)) {
2930 streamer = this.member_streamer;
2932 streamer = buf.fFile.GetStreamer(this.conttype, ver);
2934 this.member_streamer = streamer = buf.fFile.GetSplittedStreamer(streamer);
2935 this.member_ver = ver.val;
2936 this.member_checksum = ver.checksum;
2939 var res =
new Array(n), i, k, member;
2942 res[i] = { _typename: this.conttype };
2944 console.error(
'Fail to create split streamer for', this.conttype,
'need to read ', n,
'objects version', ver );
2946 for (k=0;k<streamer.length;++k) {
2947 member = streamer[k];
2948 if (member.split_func) {
2949 member.split_func(buf, res, n);
2952 member.func(buf, res[i]);
2959 var n = buf.ntou4(), res =
new Array(n), i = 0;
2961 if (n>200000) { console.error(
'vector streaming for of', this.conttype, n);
return res; }
2963 if (this.arrkind > 0) {
while (i<n) res[i++] = buf.ReadFastArray(buf.ntou4(), this.arrkind); }
2964 else if (this.arrkind===0) {
while (i<n) res[i++] = buf.ReadTString(); }
2965 else if (this.isptr) {
while (i<n) res[i++] = buf.ReadObjectAny(); }
2966 else if (this.submember) {
while (i<n) res[i++] = this.submember.readelem(buf); }
2967 else {
while (i<n) res[i++] = buf.ClassStreamer({}, this.conttype); }
2972 JSROOT.IO.ReadMapElement =
function(buf) {
2973 var streamer = this.streamer;
2975 if (this.member_wise) {
2977 var ver = this.stl_version;
2980 var si = buf.fFile.FindStreamerInfo(this.pairtype, ver.val, ver.checksum);
2982 if (this.si !== si) {
2983 streamer = JSROOT.IO.GetPairStreamer(si, this.pairtype, buf.fFile);
2984 if (!streamer || streamer.length!==2) {
2985 console.log(
'Fail to produce streamer for ', this.pairtype);
2992 var i, n = buf.ntoi4(), res =
new Array(n);
2995 res[i] = { _typename: this.pairtype };
2996 streamer[0].func(buf, res[i]);
2997 if (!this.member_wise) streamer[1].func(buf, res[i]);
3001 if (this.member_wise)
3002 for (i=0;i<n;++i) streamer[1].func(buf, res[i]);
3022 JSROOT.OpenFile =
function(filename, callback) {
3023 if (JSROOT.nodejs) {
3024 if (filename.indexOf(
"file://")==0)
3025 return new TNodejsFile(filename.substr(7), callback);
3027 if (filename.indexOf(
"http")!==0)
3028 return new TNodejsFile(filename, callback);
3031 if (typeof filename ===
'object' && filename.size && filename.name)
3032 return new TLocalFile(filename, callback);
3034 return new TFile(filename, callback);
3037 JSROOT.IO.NativeArray = JSROOT.nodejs || (window && (
'Float64Array' in window));
3039 JSROOT.IO.ProduceCustomStreamers();
3041 JSROOT.TBuffer = TBuffer;
3042 JSROOT.TDirectory = TDirectory;
3043 JSROOT.TFile = TFile;
3044 JSROOT.TLocalFile = TLocalFile;
3045 JSROOT.TNodejsFile = TNodejsFile;