Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TRootSnifferFull.cxx
Go to the documentation of this file.
1// $Id$
2// Author: Sergey Linev 22/12/2013
3
4/*************************************************************************
5 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TRootSnifferFull.h"
13
14#include "TH1.h"
15#include "TGraph.h"
16#include "TProfile.h"
17#include "TCanvas.h"
18#include "TFile.h"
19#include "TKey.h"
20#include "TList.h"
21#include "TMemFile.h"
22#include "TBufferFile.h"
23#include "TBufferJSON.h"
24#include "TBufferXML.h"
25#include "TROOT.h"
26#include "TFolder.h"
27#include "TTree.h"
28#include "TBranch.h"
29#include "TLeaf.h"
30#include "TClass.h"
31#include "TMethod.h"
32#include "TFunction.h"
33#include "TMethodArg.h"
34#include "TMethodCall.h"
35#include "TUrl.h"
36#include "TImage.h"
37#include "TVirtualMutex.h"
38#include "TRootSnifferStore.h"
39#include "THttpCallArg.h"
40
41#include <cstdlib>
42#include <cstring>
43
44/** \class TRootSnifferFull
45\ingroup http
46
47Extends TRootSniffer for many ROOT classes
48
49Provides access to different ROOT collections and containers
50like TTree, TCanvas, TFile, ...
51*/
52
54
55////////////////////////////////////////////////////////////////////////////////
56/// constructor
57
58TRootSnifferFull::TRootSnifferFull(const char *name, const char *objpath) : TRootSniffer(name, objpath)
59{
60}
61
62////////////////////////////////////////////////////////////////////////////////
63/// destructor
64
66{
67 delete fSinfo;
68
69 delete fMemFile;
70}
71
72////////////////////////////////////////////////////////////////////////////////
73/// return true if given class can be drawn in JSROOT
74
76{
77 if (!cl)
78 return kFALSE;
79 if (cl->InheritsFrom(TH1::Class()))
80 return kTRUE;
81 if (cl->InheritsFrom(TGraph::Class()))
82 return kTRUE;
84 return kTRUE;
86 return kTRUE;
87 return kFALSE;
88}
89
90////////////////////////////////////////////////////////////////////////////////
91/// Scans object properties
92///
93/// here such fields as `_autoload` or `_icon` properties depending on class or object name could be assigned
94/// By default properties, coded in the Class title are scanned. Example:
95///
96/// ClassDef(UserClassName, 1) // class comments *SNIFF* _field1=value _field2="string value"
97///
98/// Here *SNIFF* mark is important. After it all expressions like field=value are parsed
99/// One could use double quotes to code string values with spaces.
100/// Fields separated from each other with spaces
101
103{
104 if (obj && obj->InheritsFrom(TLeaf::Class())) {
105 rec.SetField("_more", "false", kFALSE);
106 rec.SetField("_can_draw", "false", kFALSE);
107 rec.SetField("_player", "drawLeafPlayer");
108 rec.SetField("_module", "draw_tree");
109 return;
110 }
111
113}
114
115////////////////////////////////////////////////////////////////////////////////
116/// Scans TKey properties
117///
118/// in special cases load objects from the file
119
121{
122 if (strcmp(key->GetClassName(), "TDirectoryFile") == 0) {
123 TRootSniffer::ScanKeyProperties(rec, key, obj, obj_class);
124 } else {
125 obj_class = TClass::GetClass(key->GetClassName());
126 if (obj_class && obj_class->InheritsFrom(TTree::Class())) {
127 if (rec.CanExpandItem()) {
128 // it is requested to expand tree element - read it
129 obj = key->ReadObj();
130 if (obj)
131 obj_class = obj->IsA();
132 } else {
133 rec.SetField("_ttree", "true", kFALSE); // indicate ROOT TTree
134 rec.SetField("_player", "drawTreePlayerKey");
135 rec.SetField("_module", "draw_tree");
136 // rec.SetField("_more", "true", kFALSE); // one could allow to extend
137 }
138 }
139 }
140}
141
142////////////////////////////////////////////////////////////////////////////////
143/// Scans object childs (if any)
144///
145/// here one scans collection, branches, trees and so on
146
148{
149 if (obj->InheritsFrom(TTree::Class())) {
150 if (!rec.IsReadOnly(fReadOnly)) {
151 rec.SetField("_ttree", "true", kFALSE); // indicate ROOT TTree
152 rec.SetField("_player", "drawTreePlayer");
153 rec.SetField("_module", "draw_tree");
154 }
155 ScanCollection(rec, ((TTree *)obj)->GetListOfLeaves());
156 } else if (obj->InheritsFrom(TBranch::Class())) {
157 ScanCollection(rec, ((TBranch *)obj)->GetListOfLeaves());
158 } else {
160 }
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Returns hash value for streamer infos
165///
166/// At the moment - just number of items in streamer infos list.
167
169{
170 return fSinfo ? fSinfo->GetSize() : 0;
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Return true if it is streamer info item name
175
177{
178 if (!itemname || (*itemname == 0))
179 return kFALSE;
180
181 return (strcmp(itemname, "StreamerInfo") == 0) || (strcmp(itemname, "StreamerInfo/") == 0);
182}
183
184////////////////////////////////////////////////////////////////////////////////
185/// Get hash function for specified item
186///
187/// Used to detect any changes in the specified object
188
190{
191 if (IsStreamerInfoItem(itemname))
192 return GetStreamerInfoHash();
193
194 return TRootSniffer::GetItemHash(itemname);
195}
196
197////////////////////////////////////////////////////////////////////////////////
198/// Creates TMemFile instance, which used for objects streaming
199///
200/// One could not use TBufferFile directly,
201/// while one also require streamer infos list
202
204{
205 if (fMemFile)
206 return;
207
208 TDirectory *olddir = gDirectory;
209 gDirectory = nullptr;
210 TFile *oldfile = gFile;
211 gFile = nullptr;
212
213 fMemFile = new TMemFile("dummy.file", "RECREATE");
214 gROOT->GetListOfFiles()->Remove(fMemFile);
215
216 TH1F *d = new TH1F("d", "d", 10, 0, 10);
217 fMemFile->WriteObject(d, "h1");
218 delete d;
219
220 TGraph *gr = new TGraph(10);
221 gr->SetName("abc");
222 // // gr->SetDrawOptions("AC*");
223 fMemFile->WriteObject(gr, "gr1");
224 delete gr;
225
227
228 // make primary list of streamer infos
229 TList *l = new TList();
230
231 l->Add(gROOT->GetListOfStreamerInfo()->FindObject("TGraph"));
232 l->Add(gROOT->GetListOfStreamerInfo()->FindObject("TH1F"));
233 l->Add(gROOT->GetListOfStreamerInfo()->FindObject("TH1"));
234 l->Add(gROOT->GetListOfStreamerInfo()->FindObject("TNamed"));
235 l->Add(gROOT->GetListOfStreamerInfo()->FindObject("TObject"));
236
237 fMemFile->WriteObject(l, "ll");
238 delete l;
239
241
243
244 gDirectory = olddir;
245 gFile = oldfile;
246}
247
248////////////////////////////////////////////////////////////////////////////////
249/// Search element with specified path
250///
251/// Returns pointer on element
252///
253/// Optionally one could obtain element class, member description
254/// and number of childs. When chld!=0, not only element is searched,
255/// but also number of childs are counted. When member!=0, any object
256/// will be scanned for its data members (disregard of extra options)
257
258void *TRootSnifferFull::FindInHierarchy(const char *path, TClass **cl, TDataMember **member, Int_t *chld)
259{
260 if (IsStreamerInfoItem(path)) {
261 // special handling for streamer info
263 if (cl && fSinfo)
264 *cl = fSinfo->IsA();
265 return fSinfo;
266 }
267
268 return TRootSniffer::FindInHierarchy(path, cl, member, chld);
269}
270
271////////////////////////////////////////////////////////////////////////////////
272/// Produce binary data for specified item
273///
274/// if "zipped" option specified in query, buffer will be compressed
275
276Bool_t TRootSnifferFull::ProduceBinary(const std::string &path, const std::string & /*query*/, std::string &res)
277{
278 if (path.empty())
279 return kFALSE;
280
281 const char *path_ = path.c_str();
282 if (*path_ == '/')
283 path_++;
284
285 TClass *obj_cl = nullptr;
286 void *obj_ptr = FindInHierarchy(path_, &obj_cl);
287 if (!obj_ptr || !obj_cl)
288 return kFALSE;
289
290 if (obj_cl->GetBaseClassOffset(TObject::Class()) != 0) {
291 Info("ProduceBinary", "Non-TObject class not supported");
292 return kFALSE;
293 }
294
295 // ensure that memfile exists
297
298 TDirectory *olddir = gDirectory;
299 gDirectory = nullptr;
300 TFile *oldfile = gFile;
301 gFile = nullptr;
302
303 TObject *obj = (TObject *)obj_ptr;
304
305 TBufferFile *sbuf = new TBufferFile(TBuffer::kWrite, 100000);
306 sbuf->SetParent(fMemFile);
307 sbuf->MapObject(obj);
308 obj->Streamer(*sbuf);
309 if (fCurrentArg)
310 fCurrentArg->SetExtraHeader("RootClassName", obj_cl->GetName());
311
312 // produce actual version of streamer info
313 delete fSinfo;
316
317 gDirectory = olddir;
318 gFile = oldfile;
319
320 res.resize(sbuf->Length());
321 std::copy((const char *)sbuf->Buffer(), (const char *)sbuf->Buffer() + sbuf->Length(), res.begin());
322
323 delete sbuf;
324
325 return kTRUE;
326}
327
328////////////////////////////////////////////////////////////////////////////////
329/// Method to produce image from specified object
330///
331/// @param kind image kind TImage::kPng, TImage::kJpeg, TImage::kGif
332/// @param path path to object
333/// @param options extra options
334/// @param res std::string with binary data
335///
336/// By default, image 300x200 is produced
337/// In options string one could provide following parameters:
338///
339/// * w - image width
340/// * h - image height
341/// * opt - draw options
342///
343/// For instance:
344///
345/// http://localhost:8080/Files/hsimple.root/hpx/get.png?w=500&h=500&opt=lego1
346
347Bool_t TRootSnifferFull::ProduceImage(Int_t kind, const std::string &path, const std::string &options, std::string &res)
348{
349 if (path.empty())
350 return kFALSE;
351
352 const char *path_ = path.c_str();
353 if (*path_ == '/')
354 path_++;
355
356 TClass *obj_cl(nullptr);
357 void *obj_ptr = FindInHierarchy(path_, &obj_cl);
358 if (!obj_ptr || !obj_cl)
359 return kFALSE;
360
361 if (obj_cl->GetBaseClassOffset(TObject::Class()) != 0) {
362 Error("TRootSniffer", "Only derived from TObject classes can be drawn");
363 return kFALSE;
364 }
365
366 TObject *obj = (TObject *)obj_ptr;
367
368 TImage *img = TImage::Create();
369 if (!img)
370 return kFALSE;
371
372 if (obj->InheritsFrom(TPad::Class())) {
373
374 if (gDebug > 1)
375 Info("TRootSniffer", "Crate IMAGE directly from pad");
376 img->FromPad((TPad *)obj);
377 } else if (CanDrawClass(obj->IsA())) {
378
379 if (gDebug > 1)
380 Info("TRootSniffer", "Crate IMAGE from object %s", obj->GetName());
381
382 Int_t width(300), height(200);
383 TString drawopt;
384
385 if (!options.empty()) {
386 TUrl url;
387 url.SetOptions(options.c_str());
388 url.ParseOptions();
389 Int_t w = url.GetIntValueFromOptions("w");
390 if (w > 10)
391 width = w;
392 Int_t h = url.GetIntValueFromOptions("h");
393 if (h > 10)
394 height = h;
395 const char *opt = url.GetValueFromOptions("opt");
396 if (opt)
397 drawopt = opt;
398 }
399
400 Bool_t isbatch = gROOT->IsBatch();
401 TVirtualPad::TContext ctxt(false);
402
403 if (!isbatch)
404 gROOT->SetBatch(kTRUE);
405
406 TCanvas *c1 = new TCanvas("__online_draw_canvas__", "title", width, height);
407 obj->Draw(drawopt.Data());
408 img->FromPad(c1);
409 delete c1;
410
411 if (!isbatch)
412 gROOT->SetBatch(kFALSE);
413
414 } else {
415 delete img;
416 return kFALSE;
417 }
418
419 TImage *im = TImage::Create();
420 im->Append(img);
421
422 char *png_buffer = nullptr;
423 int size(0);
424
425 im->GetImageBuffer(&png_buffer, &size, (TImage::EImageFileTypes)kind);
426
427 if (png_buffer && (size > 0)) {
428 res.resize(size);
429 memcpy((void *)res.data(), png_buffer, size);
430 }
431
432 free(png_buffer);
433 delete im;
434
435 return !res.empty();
436}
437
438////////////////////////////////////////////////////////////////////////////////
439/// Produce XML data for specified item
440///
441/// For object conversion TBufferXML is used
442
443Bool_t TRootSnifferFull::ProduceXml(const std::string &path, const std::string & /*options*/, std::string &res)
444{
445 if (path.empty())
446 return kFALSE;
447 const char *path_ = path.c_str();
448 if (*path_ == '/')
449 path_++;
450
451 TClass *obj_cl = nullptr;
452 void *obj_ptr = FindInHierarchy(path_, &obj_cl);
453 if (!obj_ptr || !obj_cl)
454 return kFALSE;
455
456 // TODO: support std::string in TBufferXML
457 res = TBufferXML::ConvertToXML(obj_ptr, obj_cl).Data();
458
459 return !res.empty();
460}
461
462////////////////////////////////////////////////////////////////////////////////
463/// Execute command for specified object
464///
465/// options include method and extra list of parameters
466/// sniffer should be not-readonly to allow execution of the commands
467/// @param reskind defines kind of result 0 - debug, 1 - json, 2 - binary
468
469Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &options, Int_t reskind, std::string &res_str)
470{
471 std::string *debug = (reskind == 0) ? &res_str : nullptr;
472
473 if (path.empty()) {
474 if (debug)
475 debug->append("Item name not specified\n");
476 return debug != nullptr;
477 }
478
479 const char *path_ = path.c_str();
480 if (*path_ == '/')
481 path_++;
482
483 TClass *obj_cl = nullptr;
484 void *obj_ptr = FindInHierarchy(path_, &obj_cl);
485 if (debug)
486 debug->append(Form("Item:%s found:%s\n", path_, obj_ptr ? "true" : "false"));
487 if (!obj_ptr || !obj_cl)
488 return debug != nullptr;
489
490 TUrl url;
491 url.SetOptions(options.c_str());
492
493 const char *method_name = url.GetValueFromOptions("method");
494 TString prototype = DecodeUrlOptionValue(url.GetValueFromOptions("prototype"), kTRUE);
495 TString funcname = DecodeUrlOptionValue(url.GetValueFromOptions("func"), kTRUE);
496 TMethod *method = nullptr;
497 TFunction *func = nullptr;
498 if (method_name != nullptr) {
499 if (prototype.Length() == 0) {
500 if (debug)
501 debug->append(Form("Search for any method with name \'%s\'\n", method_name));
502 method = obj_cl->GetMethodAllAny(method_name);
503 } else {
504 if (debug)
505 debug->append(Form("Search for method \'%s\' with prototype \'%s\'\n", method_name, prototype.Data()));
506 method = obj_cl->GetMethodWithPrototype(method_name, prototype);
507 }
508 }
509
510 if (method) {
511 if (debug)
512 debug->append(Form("Method: %s\n", method->GetPrototype()));
513 } else {
514 if (funcname.Length() > 0) {
515 if (prototype.Length() == 0) {
516 if (debug)
517 debug->append(Form("Search for any function with name \'%s\'\n", funcname.Data()));
518 func = gROOT->GetGlobalFunction(funcname);
519 } else {
520 if (debug)
521 debug->append(
522 Form("Search for function \'%s\' with prototype \'%s\'\n", funcname.Data(), prototype.Data()));
523 func = gROOT->GetGlobalFunctionWithPrototype(funcname, prototype);
524 }
525 }
526
527 if (func) {
528 if (debug)
529 debug->append(Form("Function: %s\n", func->GetPrototype()));
530 }
531 }
532
533 if (!method && !func) {
534 if (debug)
535 debug->append("Method not found\n");
536 return debug != nullptr;
537 }
538
539 if ((fReadOnly && (fCurrentRestrict == 0)) || (fCurrentRestrict == 1)) {
540 if ((method != nullptr) && (fCurrentAllowedMethods.Index(method_name) == kNPOS)) {
541 if (debug)
542 debug->append("Server runs in read-only mode, method cannot be executed\n");
543 return debug != nullptr;
544 } else if ((func != nullptr) && (fCurrentAllowedMethods.Index(funcname) == kNPOS)) {
545 if (debug)
546 debug->append("Server runs in read-only mode, function cannot be executed\n");
547 return debug != nullptr;
548 } else {
549 if (debug)
550 debug->append("For that special method server allows access even read-only mode is specified\n");
551 }
552 }
553
554 TList *args = method ? method->GetListOfMethodArgs() : func->GetListOfMethodArgs();
555
556 TList garbage;
557 garbage.SetOwner(kTRUE); // use as garbage collection
558 TObject *post_obj = nullptr; // object reconstructed from post request
559 TString call_args;
560
561 TIter next(args);
562 TMethodArg *arg = nullptr;
563 while ((arg = (TMethodArg *)next()) != nullptr) {
564
565 if ((strcmp(arg->GetName(), "rest_url_opt") == 0) && (strcmp(arg->GetFullTypeName(), "const char*") == 0) &&
566 (args->GetSize() == 1)) {
567 // very special case - function requires list of options after method=argument
568
569 const char *pos = strstr(options.c_str(), "method=");
570 if (!pos || (strlen(pos) < strlen(method_name) + 7))
571 return debug != nullptr;
572 const char *rest_url = pos + strlen(method_name) + 7;
573 if (*rest_url == '&') ++rest_url;
574 call_args.Form("\"%s\"", rest_url);
575 break;
576 }
577
578 TString sval;
579 const char *val = url.GetValueFromOptions(arg->GetName());
580 if (val) {
581 sval = DecodeUrlOptionValue(val, kFALSE);
582 val = sval.Data();
583 }
584
585 if ((val != nullptr) && (strcmp(val, "_this_") == 0)) {
586 // special case - object itself is used as argument
587 sval.Form("(%s*)0x%zx", obj_cl->GetName(), (size_t)obj_ptr);
588 val = sval.Data();
589 } else if ((val != nullptr) && (fCurrentArg != nullptr) && (fCurrentArg->GetPostData() != nullptr)) {
590 // process several arguments which are specific for post requests
591 if (strcmp(val, "_post_object_xml_") == 0) {
592 // post data has extra 0 at the end and can be used as null-terminated string
593 post_obj = TBufferXML::ConvertFromXML((const char *)fCurrentArg->GetPostData());
594 if (!post_obj) {
595 sval = "0";
596 } else {
597 sval.Form("(%s*)0x%zx", post_obj->ClassName(), (size_t)post_obj);
598 if (url.HasOption("_destroy_post_"))
599 garbage.Add(post_obj);
600 }
601 val = sval.Data();
602 } else if (strcmp(val, "_post_object_json_") == 0) {
603 // post data has extra 0 at the end and can be used as null-terminated string
604 post_obj = TBufferJSON::ConvertFromJSON((const char *)fCurrentArg->GetPostData());
605 if (!post_obj) {
606 sval = "0";
607 } else {
608 sval.Form("(%s*)0x%zx", post_obj->ClassName(), (size_t)post_obj);
609 if (url.HasOption("_destroy_post_"))
610 garbage.Add(post_obj);
611 }
612 val = sval.Data();
613 } else if ((strcmp(val, "_post_object_") == 0) && url.HasOption("_post_class_")) {
614 TString clname = url.GetValueFromOptions("_post_class_");
615 TClass *arg_cl = gROOT->GetClass(clname, kTRUE, kTRUE);
616 if ((arg_cl != nullptr) && (arg_cl->GetBaseClassOffset(TObject::Class()) == 0) && (post_obj == nullptr)) {
617 post_obj = (TObject *)arg_cl->New();
618 if (post_obj == nullptr) {
619 if (debug)
620 debug->append(TString::Format("Fail to create object of class %s\n", clname.Data()).Data());
621 } else {
622 if (debug)
623 debug->append(TString::Format("Reconstruct object of class %s from POST data\n", clname.Data()).Data());
625 buf.MapObject(post_obj, arg_cl);
626 post_obj->Streamer(buf);
627 if (url.HasOption("_destroy_post_"))
628 garbage.Add(post_obj);
629 }
630 }
631 sval.Form("(%s*)0x%zx", clname.Data(), (size_t)post_obj);
632 val = sval.Data();
633 } else if (strcmp(val, "_post_data_") == 0) {
634 sval.Form("(void*)0x%zx", (size_t)fCurrentArg->GetPostData());
635 val = sval.Data();
636 } else if (strcmp(val, "_post_length_") == 0) {
637 sval.Form("%ld", (long)fCurrentArg->GetPostDataLength());
638 val = sval.Data();
639 }
640 }
641
642 if (!val)
643 val = arg->GetDefault();
644
645 if (debug)
646 debug->append(Form(" Argument:%s Type:%s Value:%s \n", arg->GetName(), arg->GetFullTypeName(),
647 val ? val : "<missed>"));
648 if (!val)
649 return debug != nullptr;
650
651 if (call_args.Length() > 0)
652 call_args += ", ";
653
654 if ((strcmp(arg->GetFullTypeName(), "const char*") == 0) || (strcmp(arg->GetFullTypeName(), "Option_t*") == 0)) {
655 int len = strlen(val);
656 if ((strlen(val) < 2) || (*val != '\"') || (val[len - 1] != '\"'))
657 call_args.Append(TString::Format("\"%s\"", val));
658 else
659 call_args.Append(val);
660 } else {
661 call_args.Append(val);
662 }
663 }
664
665 TMethodCall *call = nullptr;
666
667 if (method != nullptr) {
668 call = new TMethodCall(obj_cl, method_name, call_args.Data());
669 if (debug)
670 debug->append(Form("Calling obj->%s(%s);\n", method_name, call_args.Data()));
671 } else {
672 call = new TMethodCall(funcname.Data(), call_args.Data());
673 if (debug)
674 debug->append(Form("Calling %s(%s);\n", funcname.Data(), call_args.Data()));
675 }
676
677 garbage.Add(call);
678
679 if (!call->IsValid()) {
680 if (debug)
681 debug->append("Fail: invalid TMethodCall\n");
682 return debug != nullptr;
683 }
684
685 Int_t compact = 0;
686 if (url.GetValueFromOptions("compact"))
687 compact = url.GetIntValueFromOptions("compact");
688
689 TString res = "null";
690 void *ret_obj = nullptr;
691 TClass *ret_cl = nullptr;
692 TBufferFile *resbuf = nullptr;
693 if (reskind == 2) {
694 resbuf = new TBufferFile(TBuffer::kWrite, 10000);
695 garbage.Add(resbuf);
696 }
697
698 switch (call->ReturnType()) {
699 case TMethodCall::kLong: {
700 Longptr_t l(0);
701 if (method)
702 call->Execute(obj_ptr, l);
703 else
704 call->Execute(l);
705 if (resbuf)
706 resbuf->WriteLong(l);
707 else
708 res.Form("%zd", (size_t)l);
709 break;
710 }
712 Double_t d(0.);
713 if (method)
714 call->Execute(obj_ptr, d);
715 else
716 call->Execute(d);
717 if (resbuf)
718 resbuf->WriteDouble(d);
719 else
721 break;
722 }
724 char *txt = nullptr;
725 if (method)
726 call->Execute(obj_ptr, &txt);
727 else
728 call->Execute(0, &txt); // here 0 is artificial, there is no proper signature
729 if (txt != nullptr) {
730 if (resbuf)
731 resbuf->WriteString(txt);
732 else
733 res.Form("\"%s\"", txt);
734 }
735 break;
736 }
737 case TMethodCall::kOther: {
738 std::string ret_kind = func ? func->GetReturnTypeNormalizedName() : method->GetReturnTypeNormalizedName();
739 if ((ret_kind.length() > 0) && (ret_kind[ret_kind.length() - 1] == '*')) {
740 ret_kind.resize(ret_kind.length() - 1);
741 ret_cl = gROOT->GetClass(ret_kind.c_str(), kTRUE, kTRUE);
742 }
743
744 if (ret_cl != nullptr) {
745 Longptr_t l(0);
746 if (method)
747 call->Execute(obj_ptr, l);
748 else
749 call->Execute(l);
750 if (l != 0)
751 ret_obj = (void *)l;
752 } else {
753 if (method)
754 call->Execute(obj_ptr);
755 else
756 call->Execute();
757 }
758
759 break;
760 }
761 case TMethodCall::kNone: {
762 if (method)
763 call->Execute(obj_ptr);
764 else
765 call->Execute();
766 break;
767 }
768 }
769
770 const char *_ret_object_ = url.GetValueFromOptions("_ret_object_");
771 if (_ret_object_ != nullptr) {
772 TObject *obj = nullptr;
773 if (gDirectory)
774 obj = gDirectory->Get(_ret_object_);
775 if (debug)
776 debug->append(Form("Return object %s found %s\n", _ret_object_, obj ? "true" : "false"));
777
778 if (obj == nullptr) {
779 res = "null";
780 } else {
781 ret_obj = obj;
782 ret_cl = obj->IsA();
783 }
784 }
785
786 if (ret_obj && ret_cl) {
787 if ((resbuf != nullptr) && (ret_cl->GetBaseClassOffset(TObject::Class()) == 0)) {
788 TObject *obj = (TObject *)ret_obj;
789 resbuf->MapObject(obj);
790 obj->Streamer(*resbuf);
791 if (fCurrentArg)
792 fCurrentArg->SetExtraHeader("RootClassName", ret_cl->GetName());
793 } else {
794 res = TBufferJSON::ConvertToJSON(ret_obj, ret_cl, compact);
795 }
796 }
797
798 if ((resbuf != nullptr) && (resbuf->Length() > 0)) {
799 res_str.resize(resbuf->Length());
800 std::copy((const char *)resbuf->Buffer(), (const char *)resbuf->Buffer() + resbuf->Length(), res_str.begin());
801 }
802
803 if (debug)
804 debug->append(Form("Result = %s\n", res.Data()));
805
806 if (reskind == 1)
807 res_str = res.Data();
808
809 if (url.HasOption("_destroy_result_") && ret_obj && ret_cl) {
810 ret_cl->Destructor(ret_obj);
811 if (debug)
812 debug->append("Destroy result object at the end\n");
813 }
814
815 // delete all garbage objects, but should be also done with any return
816 garbage.Delete();
817
818 return kTRUE;
819}
#define d(i)
Definition RSha256.hxx:102
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
long Longptr_t
Definition RtypesCore.h:82
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
unsigned long ULong_t
Definition RtypesCore.h:55
#define ClassImp(name)
Definition Rtypes.h:377
#define gDirectory
Definition TDirectory.h:386
#define gFile
Definition TFile.h:342
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
char name[80]
Definition TGX11.cxx:110
Int_t gDebug
Definition TROOT.cxx:585
#define gROOT
Definition TROOT.h:405
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
#define free
Definition civetweb.c:1539
A TTree is a list of TBranches.
Definition TBranch.h:89
static TClass * Class()
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
Definition TBufferFile.h:47
void WriteLong(Long_t l) override
void WriteString(const char *s) override
Write string to I/O buffer.
void WriteDouble(Double_t d) override
void MapObject(const TObject *obj, UInt_t offset=1) override
Add object to the fMap container.
static TObject * ConvertFromJSON(const char *str)
Read TObject-based class from JSON, produced by ConvertToJSON() method.
static TString ConvertToJSON(const TObject *obj, Int_t compact=0, const char *member_name=nullptr)
Converts object, inherited from TObject class, to JSON string Lower digit of compact parameter define...
static const char * GetFloatFormat()
return current printf format for float members, default "%e"
static TString ConvertToXML(const TObject *obj, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Converts object, inherited from TObject class, to XML string GenericLayout defines layout choice for ...
static TObject * ConvertFromXML(const char *str, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Read object from XML, produced by ConvertToXML() method.
void SetParent(TObject *parent)
Set parent owning this buffer.
Definition TBuffer.cxx:270
@ kWrite
Definition TBuffer.h:73
@ kRead
Definition TBuffer.h:73
Int_t Length() const
Definition TBuffer.h:100
char * Buffer() const
Definition TBuffer.h:96
The Canvas class.
Definition TCanvas.h:23
static TClass * Class()
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:4978
TMethod * GetMethodWithPrototype(const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Find the method with a given prototype.
Definition TClass.cxx:4456
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition TClass.cxx:5400
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4874
Int_t GetBaseClassOffset(const TClass *toBase, void *address=nullptr, bool isDerivedObject=true)
Definition TClass.cxx:2791
TMethod * GetMethodAllAny(const char *method)
Return pointer to method without looking at parameters.
Definition TClass.cxx:4384
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2968
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Describe directory structure in memory.
Definition TDirectory.h:45
std::enable_if_t<!std::is_base_of< TObject, T >::value, Int_t > WriteObject(const T *obj, const char *name, Option_t *option="", Int_t bufsize=0)
Write an object with proper type checking.
Definition TDirectory.h:282
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:51
virtual void WriteStreamerInfo()
Write the list of TStreamerInfo as a single object in this file The class Streamer description for al...
Definition TFile.cxx:3756
virtual TList * GetStreamerInfoList() final
Read the list of TStreamerInfo objects written to this file.
Definition TFile.cxx:1409
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
virtual const char * GetPrototype() const
Returns the prototype of a function as defined by CINT, or 0 in case of error.
TList * GetListOfMethodArgs()
Return list containing the TMethodArgs of a TFunction.
std::string GetReturnTypeNormalizedName() const
Get the normalized name of the return type.
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
static TClass * Class()
void SetName(const char *name="") override
Set graph name.
Definition TGraph.cxx:2364
1-D histogram with a float per channel (see TH1 documentation)}
Definition TH1.h:577
static TClass * Class()
const void * GetPostData() const
return pointer on posted with request data
void SetExtraHeader(const char *name, const char *value)
add extra http header value to the reply
Long_t GetPostDataLength() const
return length of posted with request data
An abstract interface to image processing library.
Definition TImage.h:29
virtual void FromPad(TVirtualPad *, Int_t=0, Int_t=0, UInt_t=0, UInt_t=0)
Definition TImage.h:122
EImageFileTypes
Definition TImage.h:36
static TImage * Create()
Create an image.
Definition TImage.cxx:35
virtual void Append(const TImage *, const char *="+", const char *="#00000000")
Definition TImage.h:175
virtual void GetImageBuffer(char **, int *, EImageFileTypes=TImage::kPng)
Definition TImage.h:241
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
virtual const char * GetClassName() const
Definition TKey.h:75
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition TKey.cxx:750
static TClass * Class()
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
TClass * IsA() const override
Definition TList.h:110
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:19
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
const char * GetDefault() const
Get default value of method argument.
Method or function calling interface.
Definition TMethodCall.h:37
EReturnType ReturnType()
Returns the return type of the method.
static const EReturnType kLong
Definition TMethodCall.h:43
static const EReturnType kString
Definition TMethodCall.h:45
static const EReturnType kOther
Definition TMethodCall.h:46
static const EReturnType kNone
Definition TMethodCall.h:49
void Execute(const char *, const char *, int *=nullptr) override
Execute method on this object with the given parameter string, e.g.
Definition TMethodCall.h:64
Bool_t IsValid() const
Return true if the method call has been properly initialized and is usable.
static const EReturnType kDouble
Definition TMethodCall.h:44
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition TMethod.cxx:307
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition TObject.cxx:882
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
static TClass * Class()
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:525
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:970
virtual TClass * IsA() const
Definition TObject.h:245
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition TObject.cxx:274
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:944
The most important graphics class in the ROOT system.
Definition TPad.h:28
static TClass * Class()
static TClass * Class()
Extends TRootSniffer for many ROOT classes.
void * FindInHierarchy(const char *path, TClass **cl=nullptr, TDataMember **member=nullptr, Int_t *chld=nullptr) override
Search element with specified path.
Bool_t IsStreamerInfoItem(const char *itemname) override
Return true if it is streamer info item name.
TRootSnifferFull(const char *name, const char *objpath="Objects")
constructor
static Bool_t IsDrawableClass(TClass *cl)
return true if given class can be drawn in JSROOT
Bool_t ProduceExe(const std::string &path, const std::string &options, Int_t reskind, std::string &res) override
Execute command for specified object.
TList * fSinfo
! last produced streamer info
Bool_t CanDrawClass(TClass *cl) override
void ScanObjectProperties(TRootSnifferScanRec &rec, TObject *obj) override
Scans object properties.
virtual ~TRootSnifferFull()
destructor
void ScanObjectChilds(TRootSnifferScanRec &rec, TObject *obj) override
Scans object childs (if any)
ULong_t GetItemHash(const char *itemname) override
Get hash function for specified item.
Bool_t ProduceImage(Int_t kind, const std::string &path, const std::string &options, std::string &res) override
Method to produce image from specified object.
Bool_t ProduceXml(const std::string &path, const std::string &options, std::string &res) override
Produce XML data for specified item.
void CreateMemFile()
Creates TMemFile instance, which used for objects streaming.
Bool_t ProduceBinary(const std::string &path, const std::string &options, std::string &res) override
Produce binary data for specified item.
TMemFile * fMemFile
! file used to manage streamer infos
ULong_t GetStreamerInfoHash() override
Returns hash value for streamer infos.
void ScanKeyProperties(TRootSnifferScanRec &rec, TKey *key, TObject *&obj, TClass *&obj_class) override
Scans TKey properties.
Structure used to scan hierarchies of ROOT objects.
Bool_t CanExpandItem()
Returns true when item can be expanded.
void SetField(const char *name, const char *value, Bool_t with_quotes=kTRUE)
Set item field only when creating is specified.
Bool_t IsReadOnly(Bool_t dflt=kTRUE)
Returns read-only flag for current item.
Sniffer of ROOT objects, data provider for THttpServer.
virtual void ScanObjectChilds(TRootSnifferScanRec &rec, TObject *obj)
scans object childs (if any) here one scans collection, branches, trees and so on
TString fCurrentAllowedMethods
! list of allowed methods, extracted when analyzed object restrictions
virtual void ScanKeyProperties(TRootSnifferScanRec &rec, TKey *key, TObject *&obj, TClass *&obj_class)
Scans TKey properties in special cases load objects from the file.
virtual void ScanObjectProperties(TRootSnifferScanRec &rec, TObject *obj)
Scans object properties here such fields as _autoload or _icon properties depending on class or objec...
TString DecodeUrlOptionValue(const char *value, Bool_t remove_quotes=kTRUE)
Method replaces all kind of special symbols, which could appear in URL options.
virtual ULong_t GetItemHash(const char *itemname)
Get hash function for specified item used to detect any changes in the specified object.
Bool_t fReadOnly
! indicate if sniffer allowed to change ROOT structures - like read objects from file
THttpCallArg * fCurrentArg
! current http arguments (if any)
virtual void * FindInHierarchy(const char *path, TClass **cl=nullptr, TDataMember **member=nullptr, Int_t *chld=nullptr)
Search element with specified path Returns pointer on element Optionally one could obtain element cla...
Int_t fCurrentRestrict
! current restriction for last-found object
void ScanCollection(TRootSnifferScanRec &rec, TCollection *lst, const char *foldername=nullptr, TCollection *keys_lst=nullptr)
Scan collection content.
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:421
const char * Data() const
Definition TString.h:380
TString & Append(const char *cs)
Definition TString.h:576
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2356
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2334
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
A TTree represents a columnar dataset.
Definition TTree.h:79
static TClass * Class()
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetValueFromOptions(const char *key) const
Return a value for a given key from the URL options.
Definition TUrl.cxx:660
Int_t GetIntValueFromOptions(const char *key) const
Return a value for a given key from the URL options as an Int_t, a missing key returns -1.
Definition TUrl.cxx:672
void SetOptions(const char *opt)
Definition TUrl.h:87
void ParseOptions() const
Parse URL options into a key/value map.
Definition TUrl.cxx:626
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.
Definition TUrl.cxx:683
small helper class to store/restore gPad context in TPad methods
Definition TVirtualPad.h:61
return c1
Definition legend1.C:41
TGraphErrors * gr
Definition legend1.C:25
TLine l
Definition textangle.C:4