00001
00002
00003
00004 (function(){
00005
00006 if (typeof JSROOT != "object") {
00007 var e1 = new Error("This extension requires JSRootCore.js");
00008 e1.source = "JSRootIOEvolution.js";
00009 throw e1;
00010 }
00011
00012 if (typeof JSROOT.IO == "object") {
00013 var e1 = new Error("This JSROOT IO already loaded");
00014 e1.source = "JSRootIOEvolution.js";
00015 throw e1;
00016 }
00017
00018 JSROOT.IO = {
00019 kBase : 0, kOffsetL : 20, kOffsetP : 40, kCounter : 6, kCharStar : 7,
00020 kChar : 1, kShort : 2, kInt : 3, kLong : 4, kFloat : 5,
00021 kDouble : 8, kDouble32 : 9, kLegacyChar : 10, kUChar : 11, kUShort : 12,
00022 kUInt : 13, kULong : 14, kBits : 15, kLong64 : 16, kULong64 : 17, kBool : 18,
00023 kFloat16 : 19,
00024 kObject : 61, kAny : 62, kObjectp : 63, kObjectP : 64, kTString : 65,
00025 kTObject : 66, kTNamed : 67, kAnyp : 68, kAnyP : 69, kAnyPnoVT : 70,
00026 kSTLp : 71,
00027 kSkip : 100, kSkipL : 120, kSkipP : 140,
00028 kConv : 200, kConvL : 220, kConvP : 240,
00029 kSTL : 300, kSTLstring : 365,
00030 kStreamer : 500, kStreamLoop : 501,
00031 kMapOffset : 2,
00032 kByteCountMask : 0x40000000,
00033 kNewClassTag : 0xFFFFFFFF,
00034 kClassMask : 0x80000000,
00035 Z_DEFLATED : 8,
00036 Z_HDRSIZE : 9
00037 };
00038
00039 JSROOT.fUserStreamers = null;
00040
00041 JSROOT.addUserStreamer = function(type, user_streamer)
00042 {
00043 if (JSROOT.fUserStreamers == null) JSROOT.fUserStreamers = {};
00044 JSROOT.fUserStreamers[type] = user_streamer;
00045 }
00046
00047 JSROOT.R__unzip_header = function(str, off, noalert) {
00048
00049
00050 if (off + JSROOT.IO.Z_HDRSIZE > str.length) {
00051 if (!noalert) alert("Error R__unzip_header: header size exceeds buffer size");
00052 return -1;
00053 }
00054
00055
00056 if (!(str.charAt(off) == 'Z' && str.charAt(off+1) == 'L' && str.charCodeAt(off+2) == JSROOT.IO.Z_DEFLATED) &&
00057 !(str.charAt(off) == 'C' && str.charAt(off+1) == 'S' && str.charCodeAt(off+2) == JSROOT.IO.Z_DEFLATED) &&
00058 !(str.charAt(off) == 'X' && str.charAt(off+1) == 'Z' && str.charCodeAt(off+2) == 0)) {
00059 if (!noalert) alert("Error R__unzip_header: error in header");
00060 return -1;
00061 }
00062 return JSROOT.IO.Z_HDRSIZE +
00063 ((str.charCodeAt(off+3) & 0xff) |
00064 ((str.charCodeAt(off+4) & 0xff) << 8) |
00065 ((str.charCodeAt(off+5) & 0xff) << 16));
00066 }
00067
00068 JSROOT.R__unzip = function(srcsize, str, off, noalert) {
00069
00070
00071 if (srcsize < JSROOT.IO.Z_HDRSIZE) {
00072 if (!noalert) alert("R__unzip: too small source");
00073 return null;
00074 }
00075
00076
00077 if (!(str.charAt(off) == 'Z' && str.charAt(off+1) == 'L' && str.charCodeAt(off+2) == JSROOT.IO.Z_DEFLATED) &&
00078 !(str.charAt(off) == 'C' && str.charAt(off+1) == 'S' && str.charCodeAt(off+2) == JSROOT.IO.Z_DEFLATED) &&
00079 !(str.charAt(off) == 'X' && str.charAt(off+1) == 'Z' && str.charCodeAt(off+2) == 0)) {
00080 if (!noalert) alert("Error R__unzip: error in header");
00081 return null;
00082 }
00083 var ibufcnt = ((str.charCodeAt(off+3) & 0xff) |
00084 ((str.charCodeAt(off+4) & 0xff) << 8) |
00085 ((str.charCodeAt(off+5) & 0xff) << 16));
00086 if (ibufcnt + JSROOT.IO.Z_HDRSIZE != srcsize) {
00087 if (!noalert) alert("R__unzip: discrepancy in source length");
00088 return null;
00089 }
00090
00091
00092 if (str.charAt(off) == 'Z' && str.charAt(off+1) == 'L') {
00093
00094 var data = str.substr(off + JSROOT.IO.Z_HDRSIZE + 2, srcsize);
00095 return RawInflate.inflate(data);
00096 }
00097
00098 else {
00099 if (!noalert) alert("R__unzip: Old zlib format is not supported!");
00100 return null;
00101 }
00102 return null;
00103 };
00104
00105
00106 JSROOT.ReconstructObject = function(class_name, obj_rawdata, sinfo_rawdata) {
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 var file = new JSROOT.TFile;
00119 var buf = new JSROOT.TBuffer(sinfo_rawdata, 0, file);
00120 file.ExtractStreamerInfos(buf);
00121
00122 var obj = {};
00123
00124 buf = new JSROOT.TBuffer(obj_rawdata, 0, file);
00125 buf.MapObject(obj, 1);
00126 buf.ClassStreamer(obj, class_name);
00127
00128 return obj;
00129 }
00130
00131 JSROOT.TBuffer = function(_str, _o, _file) {
00132 this._typename = "TBuffer";
00133 this.b = _str;
00134 this.o = (_o==null) ? 0 : _o;
00135 this.fFile = _file;
00136 this.ClearObjectMap();
00137 this.fTagOffset = 0;
00138 return this;
00139 }
00140
00141 JSROOT.TBuffer.prototype.locate = function(pos) {
00142 this.o = pos;
00143 }
00144
00145 JSROOT.TBuffer.prototype.shift = function(cnt) {
00146 this.o += cnt;
00147 }
00148
00149 JSROOT.TBuffer.prototype.ntou1 = function() {
00150 return (this.b.charCodeAt(this.o++) & 0xff) >>> 0;
00151 }
00152
00153 JSROOT.TBuffer.prototype.ntou2 = function() {
00154
00155 var n = ((this.b.charCodeAt(this.o) & 0xff) << 8) >>> 0;
00156 n += (this.b.charCodeAt(this.o+1) & 0xff) >>> 0;
00157 this.o += 2;
00158 return n;
00159 };
00160
00161 JSROOT.TBuffer.prototype.ntou4 = function() {
00162
00163 var n = ((this.b.charCodeAt(this.o) & 0xff) << 24) >>> 0;
00164 n += ((this.b.charCodeAt(this.o+1) & 0xff) << 16) >>> 0;
00165 n += ((this.b.charCodeAt(this.o+2) & 0xff) << 8) >>> 0;
00166 n += (this.b.charCodeAt(this.o+3) & 0xff) >>> 0;
00167 this.o += 4;
00168 return n;
00169 };
00170
00171 JSROOT.TBuffer.prototype.ntou8 = function() {
00172
00173 var n = ((this.b.charCodeAt(this.o) & 0xff) << 56) >>> 0;
00174 n += ((this.b.charCodeAt(this.o+1) & 0xff) << 48) >>> 0;
00175 n += ((this.b.charCodeAt(this.o+2) & 0xff) << 40) >>> 0;
00176 n += ((this.b.charCodeAt(this.o+3) & 0xff) << 32) >>> 0;
00177 n += ((this.b.charCodeAt(this.o+4) & 0xff) << 24) >>> 0;
00178 n += ((this.b.charCodeAt(this.o+5) & 0xff) << 16) >>> 0;
00179 n += ((this.b.charCodeAt(this.o+6) & 0xff) << 8) >>> 0;
00180 n += (this.b.charCodeAt(this.o+7) & 0xff) >>> 0;
00181 this.op += 8;
00182 return n;
00183 };
00184
00185 JSROOT.TBuffer.prototype.ntoi1 = function() {
00186 return (this.b.charCodeAt(this.o++) & 0xff);
00187 }
00188
00189 JSROOT.TBuffer.prototype.ntoi2 = function() {
00190
00191 var n = (this.b.charCodeAt(this.o) & 0xff) << 8;
00192 n += (this.b.charCodeAt(this.o+1) & 0xff);
00193 this.o += 2;
00194 return n;
00195 };
00196
00197 JSROOT.TBuffer.prototype.ntoi4 = function() {
00198
00199 var n = ((this.b.charCodeAt(this.o) & 0xff) << 24) +
00200 ((this.b.charCodeAt(this.o+1) & 0xff) << 16) +
00201 ((this.b.charCodeAt(this.o+2) & 0xff) << 8) +
00202 ((this.b.charCodeAt(this.o+3) & 0xff));
00203 this.o += 4;
00204 return n;
00205 };
00206
00207 JSROOT.TBuffer.prototype.ntoi8 = function(b, o) {
00208
00209 var n = (this.b.charCodeAt(this.o) & 0xff) << 56;
00210 n += (this.b.charCodeAt(this.o+1) & 0xff) << 48;
00211 n += (this.b.charCodeAt(this.o+2) & 0xff) << 40;
00212 n += (this.b.charCodeAt(this.o+3) & 0xff) << 32;
00213 n += (this.b.charCodeAt(this.o+4) & 0xff) << 24;
00214 n += (this.b.charCodeAt(this.o+5) & 0xff) << 16;
00215 n += (this.b.charCodeAt(this.o+6) & 0xff) << 8;
00216 n += (this.b.charCodeAt(this.o+7) & 0xff);
00217 this.o += 8;
00218 return n;
00219 };
00220
00221 JSROOT.TBuffer.prototype.ntof = function() {
00222
00223 var inString = this.b.substring(this.o, this.o + 4); this.o+=4;
00224 if (inString.length < 4) return Number.NaN;
00225 var bits = "";
00226 for (var i=0; i<4; i++) {
00227 var curByte = (inString.charCodeAt(i) & 0xff).toString(2);
00228 var byteLen = curByte.length;
00229 if (byteLen < 8) {
00230 for (var bit=0; bit<(8-byteLen); bit++)
00231 curByte = '0' + curByte;
00232 }
00233 bits = bits + curByte;
00234 }
00235
00236 var bsign = (bits.charAt(0) == '1') ? -1 : 1;
00237 var bexp = parseInt(bits.substring(1, 9), 2) - 127;
00238 var bman;
00239 if (bexp == -127)
00240 bman = 0;
00241 else {
00242 bman = 1;
00243 for (var i=0; i<23; i++) {
00244 if (parseInt(bits.substr(9+i, 1)) == 1)
00245 bman = bman + 1 / Math.pow(2, i+1);
00246 }
00247 }
00248 return (bsign * Math.pow(2, bexp) * bman);
00249 };
00250
00251 JSROOT.TBuffer.prototype.ntod = function() {
00252
00253 var inString = this.b.substring(this.o, this.o + 8); this.o+=8;
00254 if (inString.length < 8) return Number.NaN;
00255 var bits = "";
00256 for (var i=0; i<8; i++) {
00257 var curByte = (inString.charCodeAt(i) & 0xff).toString(2);
00258 var byteLen = curByte.length;
00259 if (byteLen < 8) {
00260 for (var bit=0; bit<(8-byteLen); bit++)
00261 curByte = '0' + curByte;
00262 }
00263 bits = bits + curByte;
00264 }
00265
00266 var bsign = (bits.charAt(0) == '1') ? -1 : 1;
00267 var bexp = parseInt(bits.substring(1, 12), 2) - 1023;
00268 var bman;
00269 if (bexp == -127)
00270 bman = 0;
00271 else {
00272 bman = 1;
00273 for (var i=0; i<52; i++) {
00274 if (parseInt(bits.substr(12+i, 1)) == 1)
00275 bman = bman + 1 / Math.pow(2, i+1);
00276 }
00277 }
00278 return (bsign * Math.pow(2, bexp) * bman);
00279 };
00280
00281
00282 JSROOT.TBuffer.prototype.ReadFastArray = function(n, array_type) {
00283
00284 var array = new Array();
00285 switch (array_type) {
00286 case 'D':
00287 for (var i = 0; i < n; ++i) {
00288 array[i] = this.ntod();
00289 if (Math.abs(array[i]) < 1e-300) array[i] = 0.0;
00290 }
00291 break;
00292 case 'F':
00293 for (var i = 0; i < n; ++i) {
00294 array[i] = this.ntof();
00295 if (Math.abs(array[i]) < 1e-300) array[i] = 0.0;
00296 }
00297 break;
00298 case 'L':
00299 for (var i = 0; i < n; ++i)
00300 array[i] = this.ntoi8();
00301 break;
00302 case 'LU':
00303 for (var i = 0; i < n; ++i)
00304 array[i] = this.ntou8();
00305 break;
00306 case 'I':
00307 for (var i = 0; i < n; ++i)
00308 array[i] = this.ntoi4();
00309 break;
00310 case 'U':
00311 for (var i = 0; i < n; ++i)
00312 array[i] = this.ntou4();
00313 break;
00314 case 'S':
00315 for (var i = 0; i < n; ++i)
00316 array[i] = this.ntoi2();
00317 break;
00318 case 'C':
00319 for (var i = 0; i < n; ++i)
00320 array[i] = this.b.charCodeAt(this.o++) & 0xff;
00321 break;
00322 case 'TString':
00323 for (var i = 0; i < n; ++i)
00324 array[i] = this.ReadTString();
00325 break;
00326 default:
00327 for (var i = 0; i < n; ++i)
00328 array[i] = this.ntou4();
00329 break;
00330 }
00331 return array;
00332 };
00333
00334
00335 JSROOT.TBuffer.prototype.ReadBasicPointer = function(len, array_type) {
00336 var isArray = this.b.charCodeAt(this.o++) & 0xff;
00337 if (isArray)
00338 return this.ReadFastArray(len, array_type);
00339
00340 if (len==0) return new Array();
00341
00342 this.o--;
00343 return this.ReadFastArray(len, array_type);
00344 };
00345
00346
00347 JSROOT.TBuffer.prototype.ReadString = function(max_len) {
00348
00349 max_len = typeof(max_len) != 'undefined' ? max_len : 0;
00350 var len = 0;
00351 var pos0 = this.o;
00352 while ((max_len==0) || (len<max_len)) {
00353 if ((this.b.charCodeAt(this.o++) & 0xff) == 0) break;
00354 len++;
00355 }
00356
00357 return (len == 0) ? "" : this.b.substring(pos0, pos0 + len);
00358 };
00359
00360 JSROOT.TBuffer.prototype.ReadTString = function() {
00361
00362 var len = this.b.charCodeAt(this.o++) & 0xff;
00363
00364 if (len == 255) len = this.ntou4();
00365
00366 var pos = this.o;
00367 this.o += len;
00368
00369 return (this.b.charCodeAt(pos) == 0) ? '' : this.b.substring(pos, pos + len);
00370 };
00371
00372
00373 JSROOT.TBuffer.prototype.GetMappedObject = function(tag) {
00374 return this.fObjectMap[tag];
00375 };
00376
00377 JSROOT.TBuffer.prototype.MapObject = function(tag, obj) {
00378 if (obj==null) return;
00379 this.fObjectMap[tag] = obj;
00380 };
00381
00382 JSROOT.TBuffer.prototype.MapClass = function(tag, classname) {
00383 this.fClassMap[tag] = classname;
00384 };
00385
00386 JSROOT.TBuffer.prototype.GetMappedClass = function(tag) {
00387 if (tag in this.fClassMap) return this.fClassMap[tag];
00388 return -1;
00389 };
00390
00391 JSROOT.TBuffer.prototype.ClearObjectMap = function() {
00392 this.fObjectMap = {};
00393 this.fClassMap = {};
00394 this.fObjectMap[0] = null;
00395 };
00396
00397 JSROOT.TBuffer.prototype.ReadVersion = function() {
00398
00399 var ver = {};
00400 var bytecnt = this.ntou4();
00401 if (bytecnt & JSROOT.IO.kByteCountMask)
00402 ver['bytecnt'] = bytecnt - JSROOT.IO.kByteCountMask - 2;
00403 ver['val'] = this.ntou2();
00404 ver['off'] = this.o;
00405 return ver;
00406 };
00407
00408 JSROOT.TBuffer.prototype.CheckBytecount = function(ver, where) {
00409 if (('bytecnt' in ver) && (ver['off'] + ver['bytecnt'] != this.o)) {
00410 if (where!=null)
00411 alert("Missmatch in " + where + " bytecount expected = " + ver['bytecnt'] + " got = " + (this.o-ver['off']));
00412 this.o = ver['off'] + ver['bytecnt'];
00413 return false;
00414 }
00415 return true;
00416 }
00417
00418 JSROOT.TBuffer.prototype.ReadTObject = function(tobj) {
00419 this.o += 2;
00420 if ((!'_typename' in tobj) || (tobj['_typename'] == ''))
00421 tobj['_typename'] = "TObject";
00422
00423 tobj['fUniqueID'] = this.ntou4();
00424 tobj['fBits'] = this.ntou4();
00425 return true;
00426 }
00427
00428 JSROOT.TBuffer.prototype.ReadTNamed = function(tobj) {
00429
00430 var ver = this.ReadVersion();
00431 this.ReadTObject(tobj);
00432 tobj['fName'] = this.ReadTString();
00433 tobj['fTitle'] = this.ReadTString();
00434 return this.CheckBytecount(ver, "ReadTNamed");
00435 };
00436
00437 JSROOT.TBuffer.prototype.ReadTObjString = function(tobj) {
00438
00439 var ver = this.ReadVersion();
00440 this.ReadTObject(tobj);
00441 tobj['fString'] = this.ReadTString();
00442 return this.CheckBytecount(ver, "ReadTObjString");
00443 }
00444
00445 JSROOT.TBuffer.prototype.ReadTList = function(list) {
00446
00447 list['_typename'] = "TList";
00448 list['name'] = "";
00449 list['arr'] = new Array;
00450 list['opt'] = new Array;
00451 var ver = this.ReadVersion();
00452 if (ver['val'] > 3) {
00453 this.ReadTObject(list);
00454 list['name'] = this.ReadTString();
00455 var nobjects = this.ntou4();
00456 for (var i = 0; i < nobjects; ++i) {
00457
00458 var obj = this.ReadObjectAny();
00459 list['arr'].push(obj);
00460
00461 var opt = this.ReadTString();
00462 list['opt'].push(opt);
00463 }
00464 }
00465
00466 return this.CheckBytecount(ver);
00467 }
00468
00469 JSROOT.TBuffer.prototype.ReadTObjArray = function(list) {
00470 list['_typename'] = "TObjArray";
00471 list['name'] = "";
00472 list['arr'] = new Array();
00473 var ver = this.ReadVersion();
00474 if (ver['val'] > 2)
00475 this.ReadTObject(list);
00476 if (ver['val'] > 1)
00477 list['name'] = this.ReadTString();
00478 var nobjects = this.ntou4();
00479 var lowerbound = this.ntou4();
00480 for (var i = 0; i < nobjects; i++) {
00481 var obj = this.ReadObjectAny();
00482 list['arr'].push(obj);
00483 }
00484 return this.CheckBytecount(ver, "ReadTObjArray");
00485 };
00486
00487 JSROOT.TBuffer.prototype.ReadTClonesArray = function(list) {
00488 list['_typename'] = "TClonesArray";
00489 list['name'] = "";
00490 list['arr'] = new Array();
00491 var ver = this.ReadVersion();
00492 if (ver['val'] > 2)
00493 this.ReadTObject(list);
00494 if (ver['val'] > 1)
00495 list['name'] = this.ReadTString();
00496 var s = this.ReadTString();
00497 var classv = s;
00498 var clv = 0;
00499 var pos = s.indexOf(";");
00500 if (pos != -1) {
00501 classv = s.slice(0, pos);
00502 s = s.slice(pos+1, s.length()-pos-1);
00503 clv = parseInt(s);
00504 }
00505 var nobjects = this.ntou4();
00506 if (nobjects < 0) nobjects = -nobjects;
00507 var lowerbound = this.ntou4();
00508 for (var i = 0; i < nobjects; i++) {
00509 var obj = {};
00510
00511 this.ClassStreamer(obj, classv);
00512
00513 list['arr'].push(obj);
00514 }
00515 return this.CheckBytecount(ver, "ReadTClonesArray");
00516 }
00517
00518 JSROOT.TBuffer.prototype.ReadTPolyMarker3D = function(marker) {
00519 var ver = this.ReadVersion();
00520
00521 this.ReadTObject(marker);
00522
00523 this.ClassStreamer(marker, "TAttMarker");
00524
00525 marker['fN'] = this.ntoi4();
00526
00527 marker['fP'] = this.ReadFastArray(marker['fN']*3, 'F');
00528
00529 marker['fOption'] = this.ReadTString();
00530
00531 if (ver['val'] > 1)
00532 marker['fName'] = this.ReadTString();
00533 else
00534 marker['fName'] = "TPolyMarker3D";
00535
00536 return this.CheckBytecount(ver, "ReadTPolyMarker3D");
00537 }
00538
00539 JSROOT.TBuffer.prototype.ReadTCollection = function(list, str, o) {
00540 list['_typename'] = "TCollection";
00541 list['name'] = "";
00542 list['arr'] = new Array();
00543 var ver = this.ReadVersion();
00544 if (ver['val'] > 2)
00545 this.ReadTObject(list);
00546 if (ver['val'] > 1)
00547 list['name'] = this.ReadTString();
00548 var nobjects = this.ntou4();
00549 for (var i = 0; i < nobjects; i++) {
00550 o += 10;
00551 list['arr'].push(null);
00552 }
00553 return this.CheckBytecount(ver,"ReadTCollection");
00554 }
00555
00556 JSROOT.TBuffer.prototype.ReadTCanvas = function(obj) {
00557
00558 var ver = this.ReadVersion();
00559
00560 this.ClassStreamer(obj, "TPad");
00561
00562 obj['fDISPLAY'] = this.ReadTString();
00563 obj['fDoubleBuffer'] = this.ntoi4();
00564 obj['fRetained'] = this.ntou1()!=0;
00565 obj['fXsizeUser'] = this.ntoi4();
00566 obj['fYsizeUser'] = this.ntoi4();
00567 obj['fXsizeReal'] = this.ntoi4();
00568 obj['fYsizeReal'] = this.ntoi4();
00569 obj['fWindowTopX'] = this.ntoi4();
00570 obj['fWindowTopY'] = this.ntoi4();
00571 obj['fWindowWidth'] = this.ntoi4();
00572 obj['fWindowHeight'] = this.ntoi4();
00573 obj['fCw'] = this.ntou4();
00574 obj['fCh'] = this.ntou4();
00575
00576 obj['fCatt'] = {};
00577 this.ClassStreamer(obj['fCatt'], "TAttCanvas");
00578 this.ntou1();
00579 this.ntou1();
00580 obj['fHighLightColor'] = this.ntoi2();
00581 obj['fBatch'] = this.ntou1()!=0;
00582 this.ntou1();
00583 this.ntou1();
00584 this.ntou1();
00585
00586
00587 return this.CheckBytecount(ver, "TCanvas");
00588 }
00589
00590
00591 JSROOT.TBuffer.prototype.ReadTStreamerInfo = function(streamerinfo) {
00592
00593
00594 var R__v = this.ReadVersion();
00595 if (R__v['val'] > 1) {
00596 this.ReadTNamed(streamerinfo);
00597
00598 streamerinfo['fCheckSum'] = this.ntou4();
00599 streamerinfo['fClassVersion'] = this.ntou4();
00600
00601 streamerinfo['fElements'] = this.ReadObjectAny();
00602 }
00603 return this.CheckBytecount(R__v, "ReadTStreamerInfo");
00604 };
00605
00606 JSROOT.TBuffer.prototype.ReadStreamerElement = function(element) {
00607
00608
00609 var R__v = this.ReadVersion();
00610 this.ReadTNamed(element);
00611 element['type'] = this.ntou4();
00612 element['size'] = this.ntou4();
00613 element['length'] = this.ntou4();
00614 element['dim'] = this.ntou4();
00615 if (R__v['val'] == 1) {
00616 var n = this.ntou4();
00617 element['maxindex'] = this.ReadFastArray(n, 'U');
00618 } else {
00619 element['maxindex'] = this.ReadFastArray(5, 'U');
00620 }
00621 element['fTypeName'] = this.ReadTString();
00622 element['typename'] = element['fTypeName'];
00623 if ((element['type'] == 11) && (element['typename'] == "Bool_t" ||
00624 element['typename'] == "bool"))
00625 element['type'] = 18;
00626 if (R__v['val'] > 1) {
00627 element['uuid'] = 0;
00628 }
00629 if (R__v['val'] <= 2) {
00630
00631
00632
00633 }
00634 if (R__v['val'] == 3) {
00635 element['xmin'] = this.ntou4();
00636 element['xmax'] = this.ntou4();
00637 element['factor'] = this.ntou4();
00638
00639 }
00640 if (R__v['val'] > 3) {
00641
00642 }
00643 return this.CheckBytecount(R__v, "ReadStreamerElement");
00644 };
00645
00646
00647 JSROOT.TBuffer.prototype.ReadStreamerBase = function(streamerbase) {
00648
00649
00650 var R__v = this.ReadVersion();
00651 this.ReadStreamerElement(streamerbase);
00652 if (R__v['val'] > 2) {
00653 streamerbase['baseversion'] = this.ntou4();
00654 }
00655 return this.CheckBytecount(R__v, "ReadStreamerBase");
00656 };
00657
00658 JSROOT.TBuffer.prototype.ReadStreamerBasicType = function(streamerbase) {
00659
00660 var R__v = this.ReadVersion();
00661 if (R__v['val'] > 1) {
00662 this.ReadStreamerElement(streamerbase);
00663 }
00664 return this.CheckBytecount(R__v, "ReadStreamerBasicType");
00665 };
00666
00667 JSROOT.TBuffer.prototype.ReadStreamerBasicPointer = function(streamerbase) {
00668
00669 var R__v = this.ReadVersion();
00670 if (R__v['val'] > 1) {
00671 this.ReadStreamerElement(streamerbase);
00672 streamerbase['countversion'] = this.ntou4();
00673 streamerbase['countName'] = this.ReadTString();
00674 streamerbase['countClass'] = this.ReadTString();
00675 }
00676 return this.CheckBytecount(R__v, "ReadStreamerBasicPointer");
00677 };
00678
00679 JSROOT.TBuffer.prototype.ReadStreamerSTL = function(streamerSTL) {
00680
00681
00682 var R__v = this.ReadVersion();
00683 if (R__v['val'] > 2) {
00684 this.ReadStreamerElement(streamerSTL);
00685 streamerSTL['stltype'] = this.ntou4();
00686 streamerSTL['ctype'] = this.ntou4();
00687 }
00688 return this.CheckBytecount(R__v, "ReadStreamerSTL");
00689 };
00690
00691 JSROOT.TBuffer.prototype.ReadTStreamerObject = function(streamerbase) {
00692
00693 var R__v = this.ReadVersion();
00694 if (R__v['val'] > 1) {
00695 this.ReadStreamerElement(streamerbase);
00696 }
00697 return this.CheckBytecount(R__v, "ReadTStreamerObject");
00698 };
00699
00700
00701 JSROOT.TBuffer.prototype.ReadClass = function() {
00702
00703 var classInfo = {};
00704 classInfo['name'] = -1;
00705 var tag = 0;
00706 var bcnt = this.ntou4();
00707
00708 var startpos = this.o;
00709 if (!(bcnt & JSROOT.IO.kByteCountMask) || (bcnt == JSROOT.IO.kNewClassTag)) {
00710 tag = bcnt;
00711 bcnt = 0;
00712 } else {
00713
00714 tag = this.ntou4();
00715 }
00716 if (!(tag & JSROOT.IO.kClassMask)) {
00717 classInfo['objtag'] = tag;
00718 return classInfo;
00719 }
00720 if (tag == JSROOT.IO.kNewClassTag) {
00721
00722 classInfo['name'] = this.ReadString();
00723
00724 if (this.GetMappedClass(this.fTagOffset + startpos + JSROOT.IO.kMapOffset)==-1)
00725 this.MapClass(this.fTagOffset + startpos + JSROOT.IO.kMapOffset, classInfo['name']);
00726 }
00727 else {
00728
00729 var clTag = (tag & ~JSROOT.IO.kClassMask);
00730 classInfo['name'] = this.GetMappedClass(clTag);
00731
00732 if (classInfo['name']==-1) {
00733 alert("Did not found class with tag " + clTag);
00734 }
00735
00736 }
00737
00738
00739 return classInfo;
00740 };
00741
00742 JSROOT.TBuffer.prototype.ReadObjectAny = function() {
00743 var startpos = this.o;
00744 var clRef = this.ReadClass();
00745
00746
00747 if ('objtag' in clRef)
00748 return this.GetMappedObject(clRef['objtag']);
00749
00750 if (clRef['name'] == -1) return null;
00751
00752 var obj = {};
00753
00754 this.MapObject(this.fTagOffset + startpos + JSROOT.IO.kMapOffset, obj);
00755
00756 this.ClassStreamer(obj, clRef['name']);
00757
00758 return obj;
00759 };
00760
00761 JSROOT.TBuffer.prototype.ClassStreamer = function(obj, classname) {
00762
00763
00764 if (! ('_typename' in obj)) obj['_typename'] = classname;
00765
00766 if (classname == 'TObject' || classname == 'TMethodCall') {
00767 this.ReadTObject(obj);
00768 }
00769 else if (classname == 'TQObject') {
00770
00771 }
00772 else if (classname == 'TObjString') {
00773 this.ReadTObjString(obj);
00774 }
00775 else if (classname == 'TObjArray') {
00776 this.ReadTObjArray(obj);
00777 }
00778 else if (classname == 'TClonesArray') {
00779 this.ReadTClonesArray(obj);
00780 }
00781 else if ((classname == 'TList') || (classname == 'THashList')) {
00782 this.ReadTList(obj);
00783 }
00784 else if (classname == 'TCollection') {
00785 this.ReadTCollection(obj);
00786 alert("Trying to read TCollection - wrong!!!");
00787 }
00788 else if (classname == 'TCanvas') {
00789 this.ReadTCanvas(obj);
00790 }
00791 else if (classname == 'TPolyMarker3D') {
00792 this.ReadTPolyMarker3D(obj);
00793 }
00794 else if (classname == "TStreamerInfo") {
00795 this.ReadTStreamerInfo(obj);
00796 }
00797 else if (classname == "TStreamerBase") {
00798 this.ReadStreamerBase(obj);
00799 }
00800 else if (classname == "TStreamerBasicType") {
00801 this.ReadStreamerBasicType(obj);
00802 }
00803 else if ((classname == "TStreamerBasicPointer") || (classname == "TStreamerLoop")) {
00804 this.ReadStreamerBasicPointer(obj);
00805 } else if (classname == "TStreamerSTL") {
00806 this.ReadStreamerSTL(obj);
00807 } else if (classname == "TStreamerObject" ||
00808 classname == "TStreamerObjectAny" ||
00809 classname == "TStreamerString" ||
00810 classname == "TStreamerObjectPointer" ) {
00811 this.ReadTStreamerObject(obj);
00812 }
00813 else {
00814 var streamer = this.fFile.GetStreamer(classname);
00815 if (streamer != null)
00816 streamer.Stream(obj, this);
00817 else {
00818 console.log("Did not found streamer for class " + classname + " try to skip data");
00819 var ver = this.ReadVersion();
00820 this.CheckBytecount(ver);
00821 }
00822 }
00823
00824 JSROOT.addMethods(obj);
00825 }
00826
00827
00828
00829
00830
00831 JSROOT.TStreamer = function(file) {
00832 this.fFile = file;
00833 this._typename = "TStreamer";
00834 return this;
00835 };
00836
00837
00838 JSROOT.TStreamer.prototype.ReadBasicType = function(buf, obj, prop) {
00839
00840
00841 switch (this[prop]['type']) {
00842 case JSROOT.IO.kBase:
00843 break;
00844 case JSROOT.IO.kOffsetL:
00845 break;
00846 case JSROOT.IO.kOffsetP:
00847 break;
00848 case JSROOT.IO.kCharStar:
00849 var n_el = obj[this[prop]['cntname']];
00850 obj[prop] = buf.ReadBasicPointer(n_el, 'C');
00851 break;
00852 case JSROOT.IO.kChar:
00853 case JSROOT.IO.kLegacyChar:
00854 obj[prop] = buf.b.charCodeAt(buf.o++) & 0xff;
00855 break;
00856 case JSROOT.IO.kShort:
00857 obj[prop] = buf.ntoi2();
00858 break;
00859 case JSROOT.IO.kInt:
00860 case JSROOT.IO.kCounter:
00861 obj[prop] = buf.ntoi4();
00862 break;
00863 case JSROOT.IO.kLong:
00864 obj[prop] = buf.ntoi8();
00865 break;
00866 case JSROOT.IO.kFloat:
00867 case JSROOT.IO.kDouble32:
00868 obj[prop] = buf.ntof();
00869 if (Math.abs(obj[prop]) < 1e-300) obj[prop] = 0.0;
00870 break;
00871 case JSROOT.IO.kDouble:
00872 obj[prop] = buf.ntod();
00873 if (Math.abs(obj[prop]) < 1e-300) obj[prop] = 0.0;
00874 break;
00875 case JSROOT.IO.kUChar:
00876 obj[prop] = (buf.b.charCodeAt(buf.o++) & 0xff) >>> 0;
00877 break;
00878 case JSROOT.IO.kUShort:
00879 obj[prop] = buf.ntou2();
00880 break;
00881 case JSROOT.IO.kUInt:
00882 obj[prop] = buf.ntou4();
00883 break;
00884 case JSROOT.IO.kULong:
00885 obj[prop] = buf.ntou8();
00886 break;
00887 case JSROOT.IO.kBits:
00888 alert('failed to stream ' + prop + ' (' + this[prop]['typename'] + ')');
00889 break;
00890 case JSROOT.IO.kLong64:
00891 obj[prop] = buf.ntoi8();
00892 break;
00893 case JSROOT.IO.kULong64:
00894 obj[prop] = buf.ntou8();
00895 break;
00896 case JSROOT.IO.kBool:
00897 obj[prop] = (buf.b.charCodeAt(buf.o++) & 0xff) != 0;
00898 break;
00899 case JSROOT.IO.kFloat16:
00900 obj[prop] = 0;
00901 buf.o += 2;
00902 break;
00903 case JSROOT.IO.kAny:
00904 case JSROOT.IO.kAnyp:
00905 case JSROOT.IO.kObjectp:
00906 case JSROOT.IO.kObject:
00907 var classname = this[prop]['typename'];
00908 if (classname.charAt(classname.length-1) == "*")
00909 classname = classname.substr(0, classname.length - 1);
00910
00911 obj[prop] = {};
00912 buf.ClassStreamer(obj[prop], classname);
00913 break;
00914
00915 case JSROOT.IO.kAnyP:
00916 case JSROOT.IO.kObjectP:
00917 obj[prop] = buf.ReadObjectAny();
00918 break;
00919 case JSROOT.IO.kTString:
00920 obj[prop] = buf.ReadTString();
00921 break;
00922 case JSROOT.IO.kTObject:
00923 buf.ReadTObject(obj);
00924 break;
00925 case JSROOT.IO.kTNamed:
00926 buf.ReadTNamed(obj);
00927 break;
00928 case JSROOT.IO.kAnyPnoVT:
00929 case JSROOT.IO.kSTLp:
00930 case JSROOT.IO.kSkip:
00931 case JSROOT.IO.kSkipL:
00932 case JSROOT.IO.kSkipP:
00933 case JSROOT.IO.kConv:
00934 case JSROOT.IO.kConvL:
00935 case JSROOT.IO.kConvP:
00936 case JSROOT.IO.kSTL:
00937 case JSROOT.IO.kSTLstring:
00938 case JSROOT.IO.kStreamer:
00939 case JSROOT.IO.kStreamLoop:
00940 alert('failed to stream ' + prop + ' (' + this[prop]['typename'] + ')');
00941 break;
00942 case JSROOT.IO.kOffsetL+JSROOT.IO.kShort:
00943 case JSROOT.IO.kOffsetL+JSROOT.IO.kUShort:
00944 alert("Strange code was here????");
00945 var n_el = this[prop]['length'];
00946 obj[prop] = buf.ReadFastArray(n_el, 'S');
00947 break;
00948 case JSROOT.IO.kOffsetL+JSROOT.IO.kInt:
00949 var n_el = this[prop]['length'];
00950 obj[prop] = buf.ReadFastArray(n_el, 'I');
00951 break;
00952 case JSROOT.IO.kOffsetL+JSROOT.IO.kUInt:
00953 var n_el = this[prop]['length'];
00954 obj[prop] = buf.ReadFastArray(n_el, 'U');
00955 break;
00956 case JSROOT.IO.kOffsetL+JSROOT.IO.kULong:
00957 case JSROOT.IO.kOffsetL+JSROOT.IO.kULong64:
00958 var n_el = this[prop]['length'];
00959 obj[prop] = buf.ReadFastArray(n_el, 'LU');
00960 break;
00961 case JSROOT.IO.kOffsetL+JSROOT.IO.kLong:
00962 case JSROOT.IO.kOffsetL+JSROOT.IO.kLong64:
00963 var n_el = this[prop]['length'];
00964 obj[prop] = buf.ReadFastArray(n_el, 'L');
00965 break;
00966 case JSROOT.IO.kOffsetL+JSROOT.IO.kFloat:
00967 case JSROOT.IO.kOffsetL+JSROOT.IO.kDouble32:
00968
00969 var n_el = this[prop]['length'];
00970 obj[prop] = buf.ReadFastArray(n_el, 'F');
00971 break;
00972 case JSROOT.IO.kOffsetL+JSROOT.IO.kDouble:
00973
00974 var n_el = this[prop]['length'];
00975 obj[prop] = buf.ReadFastArray(n_el, 'D');
00976 break;
00977 case JSROOT.IO.kOffsetP+JSROOT.IO.kChar:
00978 var n_el = obj[this[prop]['cntname']];
00979 obj[prop] = buf.ReadBasicPointer(n_el, 'C');
00980 break;
00981 case JSROOT.IO.kOffsetP+JSROOT.IO.kShort:
00982 case JSROOT.IO.kOffsetP+JSROOT.IO.kUShort:
00983 var n_el = obj[this[prop]['cntname']];
00984 obj[prop] = buf.ReadBasicPointer(n_el, 'S');
00985 break;
00986 case JSROOT.IO.kOffsetP+JSROOT.IO.kInt:
00987 var n_el = obj[this[prop]['cntname']];
00988 obj[prop] = buf.ReadBasicPointer(n_el, 'I');
00989 break;
00990 case JSROOT.IO.kOffsetP+JSROOT.IO.kUInt:
00991 var n_el = obj[this[prop]['cntname']];
00992 obj[prop] = buf.ReadBasicPointer(n_el, 'U');
00993 break;
00994 case JSROOT.IO.kOffsetP+JSROOT.IO.kULong:
00995 case JSROOT.IO.kOffsetP+JSROOT.IO.kULong64:
00996 var n_el = obj[this[prop]['cntname']];
00997 obj[prop] = buf.ReadBasicPointer(n_el, 'LU');
00998 break;
00999 case JSROOT.IO.kOffsetP+JSROOT.IO.kLong:
01000 case JSROOT.IO.kOffsetP+JSROOT.IO.kLong64:
01001 var n_el = obj[this[prop]['cntname']];
01002 obj[prop] = buf.ReadBasicPointer(n_el, 'L');
01003 break;
01004 case JSROOT.IO.kOffsetP+JSROOT.IO.kFloat:
01005 case JSROOT.IO.kOffsetP+JSROOT.IO.kDouble32:
01006 var n_el = obj[this[prop]['cntname']];
01007 obj[prop] = buf.ReadBasicPointer(n_el, 'F');
01008 break;
01009 case JSROOT.IO.kOffsetP+JSROOT.IO.kDouble:
01010 var n_el = obj[this[prop]['cntname']];
01011 obj[prop] = buf.ReadBasicPointer(n_el, 'D');
01012 break;
01013 default:
01014 alert('failed to stream ' + prop + ' (' + this[prop]['typename'] + ')');
01015 break;
01016 }
01017 };
01018
01019 JSROOT.TStreamer.prototype.Stream = function(obj, buf) {
01020
01021 var ver = buf.ReadVersion();
01022
01023
01024 for (var prop in this) {
01025 if (!this[prop] || typeof(this[prop]) === "function")
01026 continue;
01027 if (this[prop]['typename'] === 'BASE') {
01028 var clname = this[prop]['class'];
01029 if (this[prop]['class'].indexOf("TArray") == 0) {
01030 var array_type = this[prop]['class'].charAt(6);
01031 obj['fN'] = buf.ntou4();
01032 obj['fArray'] = buf.ReadFastArray(obj['fN'], array_type);
01033 } else {
01034 buf.ClassStreamer(obj, this[prop]['class']);
01035 }
01036 }
01037 }
01038
01039 for (var prop in this) {
01040
01041 if (!this[prop] || typeof(this[prop]) === "function") continue;
01042
01043 var prop_typename = this[prop]['typename'];
01044
01045 if (typeof(prop_typename) === "undefined" || prop_typename === "BASE") continue;
01046
01047 if (JSROOT.fUserStreamers !== null) {
01048 var user_func = JSROOT.fUserStreamers[prop_typename];
01049
01050 if (user_func !== undefined) {
01051 user_func(buf, obj, prop, this);
01052 continue;
01053 }
01054 }
01055
01056
01057 switch (prop_typename) {
01058 case "TString*":
01059
01060 var r__v = buf.ReadVersion();
01061 obj[prop] = new Array();
01062 for (var i = 0; i<obj[this[prop]['cntname']]; ++i )
01063 obj[prop][i] = buf.ReadTString();
01064 buf.CheckBytecount(r__v, "TString* array");
01065 break;
01066 case "TArrayC":
01067 case "TArrayD":
01068 case "TArrayF":
01069 case "TArrayI":
01070 case "TArrayL":
01071 case "TArrayL64":
01072 case "TArrayS":
01073 var array_type = this[prop]['typename'].charAt(6);
01074 var n = buf.ntou4();
01075 obj[prop] = buf.ReadFastArray(n, array_type);
01076 break;
01077 case "TObject":
01078
01079 buf.ReadTObject(obj);
01080 break;
01081 case "TQObject":
01082
01083
01084 break;
01085 default:
01086
01087 this.ReadBasicType(buf, obj, prop);
01088 break;
01089 }
01090 }
01091 if (('fBits' in obj) && !('TestBit' in obj)) {
01092 obj['TestBit'] = function (f) {
01093 return ((obj['fBits'] & f) != 0);
01094 };
01095 }
01096
01097 buf.CheckBytecount(ver, "TStreamer.Stream");
01098
01099 return buf.o;
01100
01101 };
01102
01103
01104
01105
01106
01107
01108
01109
01110 JSROOT.TDirectory = function(file, dirname, cycle) {
01111 if (! (this instanceof arguments.callee) ) {
01112 var error = new Error("you must use new to instantiate this class");
01113 error.source = "JSROOT.TDirectory.ctor";
01114 throw error;
01115 }
01116
01117 this.fFile = file;
01118 this._typename = "TDirectory";
01119 this['dir_name'] = dirname;
01120 this['dir_cycle'] = cycle;
01121 this.fKeys = new Array();
01122 return this;
01123 };
01124
01125
01126 JSROOT.TDirectory.prototype.GetKey = function(keyname, cycle, call_back) {
01127
01128 for (var i in this.fKeys) {
01129 if (this.fKeys[i]['fName'] == keyname && this.fKeys[i]['fCycle'] == cycle) {
01130 if (typeof call_back == 'function') call_back(this.fKeys[i]);
01131 return this.fKeys[i];
01132 }
01133 }
01134
01135 var pos = keyname.lastIndexOf("/");
01136
01137 while (pos > 0) {
01138 var dirname = keyname.substr(0, pos);
01139 var subname = keyname.substr(pos+1);
01140
01141 var dirkey = this.GetKey(dirname, 1);
01142 if ((dirkey!=null) && (typeof call_back == 'function') &&
01143 (dirkey['fClassName'].indexOf("TDirectory")==0)) {
01144
01145 this.fFile.ReadObject(this['dir_name'] + "/" + dirname, 1, function(newdir) {
01146 if (newdir) newdir.GetKey(subname, cycle, call_back);
01147 });
01148 return null;
01149 }
01150
01151 pos = keyname.lastIndexOf("/", pos-1);
01152 }
01153
01154 if (typeof call_back == 'function') call_back(null);
01155 return null;
01156 }
01157
01158 JSROOT.TDirectory.prototype.ReadKeys = function(readkeys_callback) {
01159
01160 if (typeof readkeys_callback != 'function')
01161 readkeys_callback = function() {};
01162
01163 var thisdir = this;
01164 var file = this.fFile;
01165
01166
01167 var nbytes = this.fNbytesName + 22;
01168 nbytes += 4;
01169 nbytes += 4;
01170 nbytes += 18;
01171
01172 if (file.fVersion >= 40000) nbytes += 12;
01173
01174 file.Seek(this.fSeekDir, this.fFile.ERelativeTo.kBeg);
01175 file.ReadBuffer(nbytes, function(blob1) {
01176 if (blob1==null) return readkeys_callback(null);
01177 var buf = new JSROOT.TBuffer(blob1, thisdir.fNbytesName, file);
01178
01179 thisdir.StreamHeader(buf);
01180
01181
01182 buf.locate(4);
01183 var keyversion = buf.ntoi2();
01184
01185 if (keyversion > 1000) buf.shift(28);
01186 else buf.shift(20);
01187 buf.ReadTString();
01188 buf.ReadTString();
01189 thisdir.fTitle = buf.ReadTString();
01190 if (thisdir.fNbytesName < 10 || thisdir.fNbytesName > 10000) {
01191 console.log("Cannot read directory info of file " + file.fURL);
01192 return readkeys_callback(null);
01193 }
01194
01195
01196 if (thisdir.fSeekKeys <=0)
01197 return readkeys_callback(null);
01198
01199 file.Seek(thisdir.fSeekKeys, file.ERelativeTo.kBeg);
01200 file.ReadBuffer(thisdir.fNbytesKeys, function(blob2) {
01201 if (blob2 == null) readkeys_callback(null);
01202
01203 var buf = new JSROOT.TBuffer(blob2, 0, file);
01204
01205 var key = file.ReadKey(buf);
01206
01207 var nkeys = buf.ntoi4();
01208 for (var i = 0; i < nkeys; i++) {
01209 key = file.ReadKey(buf);
01210 thisdir.fKeys.push(key);
01211 }
01212 file.fDirectories.push(thisdir);
01213 delete buf;
01214
01215 readkeys_callback(thisdir);
01216 });
01217
01218 delete buf;
01219 });
01220 };
01221
01222 JSROOT.TDirectory.prototype.StreamHeader = function(buf) {
01223 var version = buf.ntou2();
01224 var versiondir = version%1000;
01225 buf.shift(8);
01226 this.fNbytesKeys = buf.ntou4();
01227 this.fNbytesName = buf.ntou4();
01228 this.fSeekDir = (version > 1000) ? buf.ntou8() : buf.ntou4();
01229 this.fSeekParent = (version > 1000) ? buf.ntou8() : buf.ntou4();
01230 this.fSeekKeys = (version > 1000) ? buf.ntou8() : buf.ntou4();
01231 if (versiondir > 2) buf.shift(18);
01232 };
01233
01234
01235
01236
01237
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262 JSROOT.TFile = function(url, newfile_callback) {
01263 if (! (this instanceof arguments.callee) ) {
01264 var error = new Error("you must use new to instantiate this class");
01265 error.source = "JSROOT.TFile.ctor";
01266 throw error;
01267 }
01268
01269 this._typename = "TFile";
01270 this.fOffset = 0;
01271 this.fEND = 0;
01272 this.fURL = url;
01273 this.fAcceptRanges = true;
01274 this.fFullFileContent = "";
01275
01276 this.ERelativeTo = { kBeg : 0, kCur : 1, kEnd : 2 };
01277 this.fDirectories = new Array();
01278 this.fKeys = new Array();
01279 this.fSeekInfo = 0;
01280 this.fNbytesInfo = 0;
01281 this.fTagOffset = 0;
01282 this.fStreamers = 0;
01283 this.fStreamerInfos = null;
01284 this.fFileName = "";
01285 this.fStreamers = new Array;
01286
01287 if (typeof this.fURL != 'string') return this;
01288
01289 if (this.fURL.charAt(this.fURL.length-1) == "+") {
01290 this.fURL = this.fURL.substr(0, this.fURL.length-1);
01291 this.fAcceptRanges = false;
01292 }
01293
01294 var pos = Math.max(this.fURL.lastIndexOf("/"), this.fURL.lastIndexOf("\\"));
01295 this.fFileName = pos>=0 ? this.fURL.substr(pos+1) : this.fURL;
01296
01297 if (!this.fAcceptRanges) {
01298 this.ReadKeys(newfile_callback);
01299 } else {
01300 var file = this;
01301
01302 var xhr = JSROOT.NewHttpRequest(this.fURL, "head", function(res) {
01303 if (res==null) {
01304 if (typeof newfile_callback == 'function')
01305 newfile_callback(null);
01306 return;
01307 }
01308
01309 var accept_ranges = res.getResponseHeader("Accept-Ranges");
01310 if (accept_ranges==null) file.fAcceptRanges = false;
01311 var len = res.getResponseHeader("Content-Length");
01312 if (len!=null) file.fEND = parseInt(len);
01313 else file.fAcceptRanges = false;
01314 file.ReadKeys(newfile_callback);
01315 });
01316
01317 xhr.send(null);
01318 }
01319
01320 return this;
01321 }
01322
01323 JSROOT.TFile.prototype.ReadBuffer = function(len, callback) {
01324
01325 if (!this.fAcceptRanges && (this.fFullFileContent.length>0))
01326 return callback(this.fFullFileContent.substr(this.fOffset, len));
01327
01328 var file = this;
01329
01330 var url = this.fURL;
01331 if (this.fAcceptRanges) {
01332
01333 if (url.indexOf('?')>0) url+="&stamp="; else url += "?stamp=";
01334 var d = new Date;
01335 url += d.getTime();
01336 }
01337
01338 var xhr = JSROOT.NewHttpRequest(url, "bin", function(res) {
01339 if ((res!=null) && !file.fAcceptRanges && (file.fFullFileContent.length == 0)) {
01340
01341 file.fFullFileContent = res;
01342 file.fEND = res.length;
01343 res = file.fFullFileContent.substr(file.fOffset, len);
01344 }
01345
01346 callback(res);
01347 });
01348
01349 if (this.fAcceptRanges)
01350 xhr.setRequestHeader("Range", "bytes=" + this.fOffset + "-" + (this.fOffset + len - 1));
01351
01352
01353 xhr.send(null);
01354 };
01355
01356 JSROOT.TFile.prototype.Seek = function(offset, pos) {
01357
01358 switch (pos) {
01359 case this.ERelativeTo.kBeg:
01360 this.fOffset = offset;
01361 break;
01362 case this.ERelativeTo.kCur:
01363 this.fOffset += offset;
01364 break;
01365 case this.ERelativeTo.kEnd:
01366
01367 if (this.fEND == 0)
01368 throw "Seek : seeking from end in file with fEND==0 is not supported";
01369 this.fOffset = this.fEND - offset;
01370 break;
01371 default:
01372 throw "Seek : unknown seek option (" + pos + ")";
01373 break;
01374 }
01375 };
01376
01377 JSROOT.TFile.prototype.ReadHeader = function(str) {
01378
01379 if (str.substring(0, 4) != "root") {
01380
01381 return null;
01382 }
01383 var header = {};
01384
01385 var buf = new JSROOT.TBuffer(str, 4, this);
01386 header['version'] = buf.ntou4();
01387 header['begin'] = buf.ntou4();
01388 var largeFile = header['version'] >= 1000000;
01389 header['end'] = largeFile ? buf.ntou8() : buf.ntou4();
01390 header['seekFree'] = largeFile ? buf.ntou8() : buf.ntou4();
01391 buf.shift(12);
01392 header['units'] = buf.ntoi1();
01393 header['fCompress'] = buf.ntou4();
01394 header['seekInfo'] = largeFile ? buf.ntou8() : buf.ntou4();
01395 header['nbytesInfo'] = buf.ntou4();
01396
01397 if (!header['seekInfo'] && !header['nbytesInfo']) {
01398
01399 return null;
01400 }
01401 this.fSeekInfo = header['seekInfo'];
01402 this.fNbytesInfo = header['nbytesInfo'];
01403 return header;
01404 };
01405
01406 JSROOT.TFile.prototype.ReadKey = function(buf) {
01407
01408 var key = {};
01409
01410 key['fNbytes'] = buf.ntoi4();
01411 key['fVersion'] = buf.ntoi2();
01412 key['fObjlen'] = buf.ntou4();
01413 var datime = buf.ntou4();
01414 key['fDatime'] = new Date();
01415 key['fDatime'].setFullYear((datime >>> 26) + 1995);
01416 key['fDatime'].setMonth((datime << 6) >>> 28);
01417 key['fDatime'].setDate((datime << 10) >>> 27);
01418 key['fDatime'].setHours((datime << 15) >>> 27);
01419 key['fDatime'].setMinutes((datime << 20) >>> 26);
01420 key['fDatime'].setSeconds((datime << 26) >>> 26);
01421 key['fDatime'].setMilliseconds(0);
01422 key['fKeylen'] = buf.ntou2();
01423 key['fCycle'] = buf.ntou2();
01424 if (key['fVersion'] > 1000) {
01425 key['fSeekKey'] = buf.ntou8();
01426 buf.shift(8);
01427 } else {
01428 key['fSeekKey'] = buf.ntou4();
01429 buf.shift(4);
01430 }
01431 key['fClassName'] = buf.ReadTString();
01432 key['fName'] = buf.ReadTString();
01433 key['fTitle'] = buf.ReadTString();
01434
01435 var name = key['fName'].replace(/['"]/g,'');
01436
01437 if (name != key['fName']) {
01438 key['fRealName'] = key['fName'];
01439 key['fName'] = name;
01440 }
01441
01442 return key;
01443 };
01444
01445 JSROOT.TFile.prototype.GetDir = function(dirname, cycle) {
01446 // check first that directory with such name exists
01447 for (var j in this.fDirectories) {
01448 var dir = this.fDirectories[j];
01449 if (dir['dir_name'] != dirname) continue;
01450 if ((cycle!=null) && (dir['dir_cycle']!=cycle)) continue;
01451 return dir;
01452 }
01453 return null;
01454 }
01455
01456 JSROOT.TFile.prototype.GetKey = function(keyname, cycle, getkey_callback) {
01457 // retrieve a key by its name and cycle in the list of keys
01458 // one should call_back when keys must be read first from the directory
01459
01460 for (var i in this.fKeys) {
01461 if (this.fKeys[i]['fName'] == keyname && this.fKeys[i]['fCycle'] == cycle) {
01462 if (typeof getkey_callback == 'function') getkey_callback(this.fKeys[i]);
01463 return this.fKeys[i];
01464 }
01465 }
01466
01467 var pos = keyname.lastIndexOf("/");
01468 // try to handle situation when object name contains slashed (bad practice anyway)
01469 while (pos > 0) {
01470 var dirname = keyname.substr(0, pos);
01471 var subname = keyname.substr(pos+1);
01472
01473 var dir = this.GetDir(dirname);
01474 if (dir!=null) return dir.GetKey(subname, cycle, getkey_callback);
01475
01476 var dirkey = this.GetKey(dirname, 1);
01477 if ((dirkey!=null) && (typeof getkey_callback == 'function') &&
01478 (dirkey['fClassName'].indexOf("TDirectory")==0)) {
01479
01480 this.ReadObject(dirname, function(newdir) {
01481 if (newdir) newdir.GetKey(subname, cycle, getkey_callback);
01482 });
01483 return null;
01484 }
01485
01486 pos = keyname.lastIndexOf("/", pos-1);
01487 }
01488
01489 if (typeof call_back == 'function') call_back(null);
01490 return null;
01491 };
01492
01493 JSROOT.TFile.prototype.ReadObjBuffer = function(key, callback) {
01494 // read and inflate object buffer described by its key
01495
01496 var file = this;
01497
01498 this.Seek(key['fSeekKey'] + key['fKeylen'], this.ERelativeTo.kBeg);
01499 this.ReadBuffer(key['fNbytes'] - key['fKeylen'], function(blob1) {
01500
01501 if (blob1==null) callback(null);
01502
01503 var buf = null;
01504
01505 if (key['fObjlen'] <= key['fNbytes']-key['fKeylen']) {
01506 buf = new JSROOT.TBuffer(blob1, 0, file);
01507 } else {
01508 var hdrsize = JSROOT.R__unzip_header(blob1, 0);
01509 if (hdrsize<0) return callback(null);
01510 var objbuf = JSROOT.R__unzip(hdrsize, blob1, 0);
01511 buf = new JSROOT.TBuffer(objbuf, 0, file);
01512 }
01513
01514 buf.fTagOffset = key.fKeylen;
01515 callback(buf);
01516 delete buf;
01517 });
01518 };
01519
01520 JSROOT.TFile.prototype.ReadObject = function(obj_name, cycle, user_call_back) {
01521 // Read any object from a root file
01522 // One could specify cycle number in the object name or as separate argument
01523 // Last argument should be callback function, while data reading from file is asynchron
01524
01525 if (typeof cycle == 'function') { user_call_back = cycle; cycle = 1; }
01526
01527 var pos = obj_name.lastIndexOf(";");
01528 if (pos>0) {
01529 cycle = parseInt(obj_name.slice(pos+1));
01530 obj_name = obj_name.slice(0, pos);
01531 }
01532
01533 if ((typeof cycle != 'number') || (cycle<0)) cycle = 1;
01534
01535 var file = this;
01536
01537 // we use callback version while in some cases we need to
01538 // read sub-directory to get list of keys
01539 // in such situation calls are asynchrone
01540 this.GetKey(obj_name, cycle, function(key) {
01541
01542 if (key == null) {
01543 if (typeof user_call_back == 'function') user_call_back(null);
01544 return;
01545 }
01546
01547 var isdir = false;
01548 if ((key['fClassName'] == 'TDirectory' || key['fClassName'] == 'TDirectoryFile')) {
01549 isdir = true;
01550 var dir = file.GetDir(obj_name, cycle);
01551 if (dir!=null) {
01552 if (typeof user_call_back == 'function') user_call_back(dir);
01553 return;
01554 }
01555 }
01556
01557 file.ReadObjBuffer(key, function(buf) {
01558 if (!buf) {
01559 if (typeof user_call_back == 'function') user_call_back(null);
01560 return;
01561 }
01562
01563 if (isdir) {
01564 var dir = new JSROOT.TDirectory(file, obj_name, cycle);
01565 dir.StreamHeader(buf);
01566 if (dir.fSeekKeys) {
01567 dir.ReadKeys(user_call_back);
01568 } else {
01569 if (typeof user_call_back == 'function') user_call_back(dir);
01570 }
01571
01572 return;
01573 }
01574
01575 var obj = {};
01576 buf.MapObject(1, obj); // tag object itself with id==1
01577 buf.ClassStreamer(obj, key['fClassName']);
01578
01579 if (typeof user_call_back == 'function') user_call_back(obj);
01580 }); // end of ReadObjBuffer callback
01581 }); // end of GetKey callback
01582 };
01583
01584 JSROOT.TFile.prototype.ExtractStreamerInfos = function(buf)
01585 {
01586 if (!buf) return;
01587
01588 var lst = {};
01589 buf.MapObject(1, lst);
01590 buf.ClassStreamer(lst, 'TList');
01591
01592 lst['_typename'] = "TStreamerInfoList";
01593
01594 this.fStreamerInfos = lst;
01595 }
01596
01597 JSROOT.TFile.prototype.ReadFormulas = function()
01598 {
01599 for (var i in this.fKeys)
01600 if (this.fKeys[i]['fClassName'] == 'TFormula')
01601 this.ReadObject(this.fKeys[i]['fName'], this.fKeys[i]['fCycle'], function(obj) {
01602 JSROOT.addFormula(obj);
01603 });
01604 }
01605
01606 JSROOT.TFile.prototype.ReadStreamerInfos = function(si_callback)
01607 {
01608 if (this.fSeekInfo == 0 || this.fNbytesInfo == 0) return si_callback(null);
01609 this.Seek(this.fSeekInfo, this.ERelativeTo.kBeg);
01610
01611 var file = this;
01612
01613 file.ReadBuffer(file.fNbytesInfo, function(blob1) {
01614 var buf = new JSROOT.TBuffer(blob1, 0, file);
01615 var key = file.ReadKey(buf);
01616 if (key == null) return si_callback(null);
01617 file.fKeys.push(key);
01618
01619 file.ReadObjBuffer(key, function(blob2) {
01620 if (blob2==null) return si_callback(null);
01621 file.ExtractStreamerInfos(blob2);
01622 file.ReadFormulas();
01623 si_callback(file);
01624 });
01625 });
01626 };
01627
01628 JSROOT.TFile.prototype.ReadKeys = function(readkeys_callback) {
01629 // read keys only in the root file
01630
01631 if (typeof readkeys_callback != 'function')
01632 readkeys_callback = function() {};
01633
01634 var file = this;
01635
01636 this.ReadBuffer(256, function(blob1) {
01637 var header = file.ReadHeader(blob1);
01638 if (header == null) return readkeys_callback(null);
01639
01640 file.ReadBuffer(300, function(blob2) {
01641 if (blob2==null) return readkeys_callback(null);
01642
01643 var buf = new JSROOT.TBuffer(blob2, 4, file); // skip the "root" file identifier
01644 file.fVersion = buf.ntou4();
01645 var headerLength = buf.ntou4();
01646 file.fBEGIN = headerLength;
01647 if (file.fVersion < 1000000) { //small file
01648 file.fEND = buf.ntou4();
01649 file.fSeekFree = buf.ntou4();
01650 file.fNbytesFree = buf.ntou4();
01651 var nfree = buf.ntoi4();
01652 file.fNbytesName = buf.ntou4();
01653 file.fUnits = buf.ntou1();
01654 file.fCompress = buf.ntou4();
01655 file.fSeekInfo = buf.ntou4();
01656 file.fNbytesInfo = buf.ntou4();
01657 } else { // new format to support large files
01658 file.fEND = buf.ntou8();
01659 file.fSeekFree = buf.ntou8();
01660 file.fNbytesFree = buf.ntou4();
01661 var nfree = buf.ntou4();
01662 file.fNbytesName = buf.ntou4();
01663 file.fUnits = buf.ntou1();
01664 file.fCompress = buf.ntou4();
01665 file.fSeekInfo = buf.ntou8();
01666 file.fNbytesInfo = buf.ntou4();
01667 }
01668 file.fSeekDir = file.fBEGIN;
01669
01670 //*-*-------------Read directory info
01671
01672 var nbytes = file.fNbytesName + 22;
01673 nbytes += 4; // fDatimeC.Sizeof();
01674 nbytes += 4; // fDatimeM.Sizeof();
01675 nbytes += 18; // fUUID.Sizeof();
01676 // assume that the file may be above 2 Gbytes if file version is > 4
01677 if (file.fVersion >= 40000) nbytes += 12;
01678
01679 file.Seek(file.fBEGIN, file.ERelativeTo.kBeg);
01680 file.ReadBuffer(Math.max(300, nbytes), function(blob3) {
01681 if (blob3==null) return readkeys_callback(null);
01682
01683 var buf = new JSROOT.TBuffer(blob3, file.fNbytesName, file);
01684 var version = buf.ntou2();
01685 var versiondir = version%1000;
01686 buf.shift(8); // skip fDatimeC and fDatimeM
01687 file.fNbytesKeys = buf.ntou4();
01688 file.fNbytesName = buf.ntou4();
01689 if (version > 1000) {
01690 file.fSeekDir = buf.ntou8();
01691 file.fSeekParent = buf.ntou8();
01692 file.fSeekKeys = buf.ntou8();
01693 } else {
01694 file.fSeekDir = buf.ntou4();
01695 file.fSeekParent = buf.ntou4();
01696 file.fSeekKeys = buf.ntou4();
01697 }
01698 if (versiondir > 1) buf.o += 18; // skip fUUID
01699
01700 //*-*---------read TKey::FillBuffer info
01701 buf.o = 4; // Skip NBytes;
01702 var keyversion = buf.ntoi2();
01703 // Skip ObjLen, DateTime, KeyLen, Cycle, SeekKey, SeekPdir
01704 if (keyversion > 1000) buf.shift(28); // Large files
01705 else buf.shift(20);
01706 buf.ReadTString();
01707 buf.ReadTString();
01708 file.fTitle = buf.ReadTString();
01709 if (file.fNbytesName < 10 || this.fNbytesName > 10000) {
01710 console.log("Init : cannot read directory info of file " + file.fURL);
01711 return readkeys_callback(null);
01712 }
01713 //*-* -------------Read keys of the top directory
01714
01715 if (file.fSeekKeys <= 0) {
01716 console.log("Empty keys list - not supported" + file.fURL);
01717 return readkeys_callback(null);
01718 }
01719
01720 file.Seek(file.fSeekKeys, file.ERelativeTo.kBeg);
01721 file.ReadBuffer(file.fNbytesKeys, function(blob4) {
01722 if (blob4==null) return readkeys_callback(null);
01723
01724 var buf = new JSROOT.TBuffer(blob4, 0, file);
01725
01726 var key = file.ReadKey(buf);
01727
01728 var nkeys = buf.ntoi4();
01729 for (var i = 0; i < nkeys; i++) {
01730 key = file.ReadKey(buf);
01731 file.fKeys.push(key);
01732 }
01733 file.ReadStreamerInfos(readkeys_callback);
01734 delete buf;
01735 });
01736 delete buf;
01737 });
01738 delete buf;
01739 });
01740 delete buf;
01741 });
01742 };
01743
01744 JSROOT.TFile.prototype.ReadDirectory = function(dir_name, cycle, readdir_callback) {
01745 // read the directory content from a root file
01746 // do not read directory if it is already exists
01747
01748 return this.ReadObject(dir_name, cycle, readdir_callback);
01749 }
01750
01751
01752 JSROOT.TFile.prototype.GetStreamer = function(clname) {
01753 // return the streamer for the class 'clname', from the list of streamers
01754 // or generate it from the streamer infos and add it to the list
01755
01756 var streamer = this.fStreamers[clname];
01757 if (typeof(streamer) != 'undefined') return streamer;
01758
01759 var s_i;
01760
01761 if (this.fStreamerInfos)
01762 for (var i in this.fStreamerInfos.arr)
01763 if (this.fStreamerInfos.arr[i].fName == clname) {
01764 s_i = this.fStreamerInfos.arr[i];
01765 break;
01766 }
01767 if (typeof s_i == 'undefined') return null;
01768
01769 this.fStreamers[clname] = new JSROOT.TStreamer(this);
01770 if (typeof(s_i['fElements']) != 'undefined') {
01771 var n_el = s_i['fElements']['arr'].length;
01772 for (var j=0;j<n_el;++j) {
01773 var element = s_i['fElements']['arr'][j];
01774 if (element['typename'] === 'BASE') {
01775 // generate streamer for the base classes
01776 this.GetStreamer(element['fName']);
01777 }
01778 }
01779 }
01780 if (typeof(s_i['fElements']) != 'undefined') {
01781 var n_el = s_i['fElements']['arr'].length;
01782 for (var j=0;j<n_el;++j) {
01783 // extract streamer info for each class member
01784 var element = s_i['fElements']['arr'][j];
01785 var streamer = {};
01786 streamer['typename'] = element['typename'];
01787 streamer['class'] = element['fName'];
01788 streamer['cntname'] = element['countName'];
01789 streamer['type'] = element['type'];
01790 streamer['length'] = element['length'];
01791
01792 this.fStreamers[clname][element['fName']] = streamer;
01793 }
01794 }
01795 return this.fStreamers[clname];
01796 };
01797
01798 JSROOT.TFile.prototype.Delete = function() {
01799 if (this.fDirectories) this.fDirectories.splice(0, this.fDirectories.length);
01800 this.fDirectories = null;
01801 if (this.fKeys) this.fKeys.splice(0, this.fKeys.length);
01802 this.fKeys = null;
01803 if (this.fStreamers) this.fStreamers.splice(0, this.fStreamers.length);
01804 this.fStreamers = null;
01805 this.fSeekInfo = 0;
01806 this.fNbytesInfo = 0;
01807 this.fTagOffset = 0;
01808 };
01809
01810 })();
01811
01812 // JSRootIOEvolution.js ends
01813