Logo ROOT  
Reference Guide
TIOFeatures.cxx
Go to the documentation of this file.
1 // Author: Brian Bockelman UNL 09/2017
2 
3 /*************************************************************************
4  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 #include "ROOT/TIOFeatures.hxx"
12 #include "TBasket.h"
13 #include "TBranch.h"
14 #include "TEnum.h"
15 #include "TEnumConstant.h"
16 #include "TError.h"
17 #include "TTree.h"
18 
19 #include <bitset>
20 #include <sstream>
21 
22 using namespace ROOT;
23 
24 /**
25  * \class ROOT::TIOFeatures
26  * \ingroup tree
27  *
28  * `TIOFeatures` provides the end-user with the ability to change the IO behavior
29  * of data written via a `TTree`. This class allows access to experimental and non-default
30  * features.
31  *
32  * When one of these features are activated, forward compatibility breaks may occur.
33  * That is, older versions of ROOT may not be able to read files written by this version
34  * of ROOT that have enabled these non-default features.
35  *
36  * To utilize `TIOFeatures`, create the object, set the desired feature flags, then attach
37  * it to a `TTree`. All subsequently created branches (and their baskets) will be serialized
38  * using those particular features.
39  *
40  * Example usage:
41  * ~~~{.cpp}
42  * ROOT::TIOFeatures features;
43  * features.Set(ROOT::Experimental::EIOFeatures::kGenerateOffsetMap);
44  * ttree_ref.SetIOFeatures(features);
45  * ~~~
46  *
47  * The method `TTree::SetIOFeatures` creates a copy of the feature set; subsequent changes
48  * to the `TIOFeatures` object do not propogate to the `TTree`.
49  */
50 
51 
52 ////////////////////////////////////////////////////////////////////////////
53 /// \brief Clear a specific IO feature from this set.
54 /// \param[in] enum_bits The specific feature to disable.
55 ///
56 /// Removes a feature from the `TIOFeatures` object; emits an Error message if
57 /// the IO feature is not supported by this version of ROOT.
59 {
60  Clear(static_cast<EIOFeatures>(input_bits));
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////
64 /// \brief Clear a specific IO feature from this set.
65 /// \param[in] enum_bits The specific feature to disable.
66 ///
67 /// Removes a feature from the `TIOFeatures` object; emits an Error message if
68 /// the IO feature is not supported by this version of ROOT.
70 {
71  Clear(static_cast<EIOFeatures>(input_bits));
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////
75 /// \brief Clear a specific IO feature from this set.
76 /// \param[in] enum_bits The specific feature to disable.
77 ///
78 /// Removes a feature from the `TIOFeatures` object; emits an Error message if
79 /// the IO feature is not supported by this version of ROOT.
81 {
82  TBasket::EIOBits enum_bits = static_cast<TBasket::EIOBits>(input_bits);
83  auto bits = static_cast<UChar_t>(enum_bits);
84  if (R__unlikely((bits & static_cast<UChar_t>(TBasket::EIOBits::kSupported)) != bits)) {
85  Error("TestFeature", "A feature is being cleared that is not supported.");
86  return;
87  }
88  fIOBits &= ~bits;
89 }
90 
91 static std::string GetUnsupportedName(TBasket::EUnsupportedIOBits enum_flag)
92 {
93  UChar_t flag = static_cast<UChar_t>(enum_flag);
94 
95  std::string retval = "unknown";
96 
97  TClass *cl = TBasket::Class();
98  if (cl == nullptr) {
99  return retval;
100  }
101 
102  TEnum *eUnsupportedIOBits = (TEnum *)cl->GetListOfEnums()->FindObject("EUnsupportedIOBits");
103  if (eUnsupportedIOBits == nullptr) {
104  return retval;
105  }
106 
107  for (auto constant : ROOT::Detail::TRangeStaticCast<TEnumConstant>(eUnsupportedIOBits->GetConstants())) {
108  if (constant->GetValue() == flag) {
109  retval = constant->GetName();
110  break;
111  }
112  }
113  return retval;
114 }
115 
116 ////////////////////////////////////////////////////////////////////////////
117 /// \brief Set a specific IO feature.
118 /// \param[in] enum_bits The specific feature to enable.
119 ///
120 /// Sets a feature in the `TIOFeatures` object; emits an Error message if
121 /// the IO feature is not supported by this version of ROOT.
122 ///
123 /// If the feature is supported by ROOT, this function returns kTRUE; otherwise,
124 /// it returns kFALSE.
126 {
127  return Set(static_cast<EIOFeatures>(input_bits));
128 }
129 
130 ////////////////////////////////////////////////////////////////////////////
131 /// \brief Set a specific IO feature.
132 /// \param[in] enum_bits The specific feature to enable.
133 ///
134 /// Sets a feature in the `TIOFeatures` object; emits an Error message if
135 /// the IO feature is not supported by this version of ROOT.
136 ///
137 /// If the feature is supported by ROOT, this function returns kTRUE; otherwise,
138 /// it returns kFALSE.
140 {
141  TBasket::EIOBits enum_bits = static_cast<TBasket::EIOBits>(input_bits);
142  auto bits = static_cast<UChar_t>(enum_bits);
143  if (R__unlikely((bits & static_cast<UChar_t>(TBasket::EIOBits::kSupported)) != bits)) {
144  UChar_t unsupported = bits & static_cast<UChar_t>(TBasket::EUnsupportedIOBits::kUnsupported);
145  if (unsupported) {
146  Error("SetFeature", "A feature was request (%s) but this feature is no longer supported.",
147  GetUnsupportedName(static_cast<TBasket::EUnsupportedIOBits>(unsupported)).c_str());
148  } else {
149  Error("SetFeature", "An unknown feature was requested (flag=%s); cannot enable it.",
150  std::bitset<32>(unsupported).to_string().c_str());
151  }
152  return kFALSE;
153  }
154  fIOBits |= bits;
155  return kTRUE;
156 }
157 
158 
159 /////////////////////////////////////////////////////////////////////////////
160 /// \brief Given a IO feature string, set the corresponding feature
161 /// \param [in] value Feature name to test.
162 ///
163 /// This allows one to set a feature given a specific string from the
164 /// TBasket::EIOBits enum.
165 ///
166 /// *NOTE* this function is quite slow and users are strongly encouraged to
167 /// use the type-safe `Set` version instead. This has been added for better
168 /// CLI interfaces.
169 ///
170 /// Returns kTRUE only if a new feature was set; otherwise emits an error message
171 /// and returns kFALSE.
172 bool TIOFeatures::Set(const std::string &value)
173 {
174  TClass *cl = TBasket::Class();
175  if (cl == nullptr) {
176  Error("Set", "Could not retrieve TBasket's class");
177  return kFALSE;
178  }
179  TEnum *eIOBits = static_cast<TEnum*>(cl->GetListOfEnums()->FindObject("EIOBits"));
180  if (eIOBits == nullptr) {
181  Error("Set", "Could not locate TBasket::EIOBits enum");
182  return kFALSE;
183  }
184  for (auto constant : ROOT::Detail::TRangeStaticCast<TEnumConstant>(eIOBits->GetConstants())) {
185  if (!strcmp(constant->GetName(), value.c_str())) {
186  return Set(static_cast<EIOFeatures>(constant->GetValue()));
187  }
188  }
189  Error("Set", "Could not locate %s in TBasket::EIOBits", value.c_str());
190  return kFALSE;
191 }
192 
193 ////////////////////////////////////////////////////////////////////////////
194 /// \brief Print a human-readable representation of the TIOFeatures to stdout
195 ///
196 /// Prints a string with the names of all enabled IO features.
197 void TIOFeatures::Print() const
198 {
199  TClass *cl = TBasket::Class();
200  if (cl == nullptr) {
201  Error("Print", "Could not retrieve TBasket's class");
202  return;
203  }
204  TEnum *eIOBits = static_cast<TEnum *>(cl->GetListOfEnums()->FindObject("EIOBits"));
205  if (eIOBits == nullptr) {
206  Error("Print", "Could not locate TBasket::EIOBits enum");
207  return;
208  }
209  std::stringstream ss;
210  bool hasFeatures = false;
211  ss << "TIOFeatures{";
212  for (auto constant : ROOT::Detail::TRangeStaticCast<TEnumConstant>(eIOBits->GetConstants())) {
213  if ((constant->GetValue() & fIOBits) == constant->GetValue()) {
214  ss << (hasFeatures ? ", " : "") << constant->GetName();
215  hasFeatures = true;
216  }
217  }
218  ss << "}";
219  Printf("%s", ss.str().c_str());
220 }
221 
222 ////////////////////////////////////////////////////////////////////////////
223 /// \brief Test to see if a given feature is set
224 /// \param[in] enum_bits The specific feature to test.
225 ///
226 /// Returns kTRUE if the feature is enables in this object and supported by
227 /// this version of ROOT.
229 {
230  return Test(static_cast<EIOFeatures>(input_bits));
231 }
232 
233 ////////////////////////////////////////////////////////////////////////////
234 /// \brief Test to see if a given feature is set
235 /// \param[in] enum_bits The specific feature to test.
236 ///
237 /// Returns kTRUE if the feature is enables in this object and supported by
238 /// this version of ROOT.
239 bool TIOFeatures::Test(EIOFeatures input_bits) const
240 {
241  TBasket::EIOBits enum_bits = static_cast<TBasket::EIOBits>(input_bits);
242  auto bits = static_cast<UChar_t>(enum_bits);
243  if (R__unlikely((bits & static_cast<UChar_t>(TBasket::EIOBits::kSupported)) != bits)) {
244  Error("TestFeature", "A feature is being tested for that is not supported or known.");
245  return kFALSE;
246  }
247  return (fIOBits & bits) == bits;
248 }
249 
251 {
252  return fIOBits;
253 }
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TEnumConstant.h
ROOT::Experimental::EIOFeatures
EIOFeatures
Definition: TIOFeatures.hxx:52
TBasket::EUnsupportedIOBits
EUnsupportedIOBits
Definition: TBasket.h:107
TList::FindObject
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
ROOT::TIOFeatures::Test
bool Test(EIOFeatures bits) const
Test to see if a given feature is set.
Definition: TIOFeatures.cxx:239
TBranch.h
TIOFeatures.hxx
TClass::GetListOfEnums
TList * GetListOfEnums(Bool_t load=kTRUE)
Return a list containing the TEnums of a class.
Definition: TClass.cxx:3609
TTree.h
TObject::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
TEnum::GetConstants
const TSeqCollection * GetConstants() const
Definition: TEnum.h:59
ROOT::TIOFeatures::Print
void Print() const
Print a human-readable representation of the TIOFeatures to stdout.
Definition: TIOFeatures.cxx:197
ROOT::TIOFeatures::Clear
void Clear(EIOFeatures bits)
Clear a specific IO feature from this set.
Definition: TIOFeatures.cxx:80
TEnum.h
TEnum
Definition: TEnum.h:33
ROOT::Detail::TRangeStaticCast
TRangeStaticCast is an adaptater class that allows the typed iteration through a TCollection.
Definition: TCollection.h:382
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
R__unlikely
#define R__unlikely(expr)
Definition: RConfig.hxx:604
ROOT::EIOFeatures
EIOFeatures
Definition: TIOFeatures.hxx:39
TBasket::EUnsupportedIOBits::kUnsupported
@ kUnsupported
ROOT::Experimental::EIOUnsupportedFeatures
EIOUnsupportedFeatures
Definition: TIOFeatures.hxx:61
GetUnsupportedName
static std::string GetUnsupportedName(TBasket::EUnsupportedIOBits enum_flag)
Definition: TIOFeatures.cxx:91
ROOT::TIOFeatures::Set
bool Set(EIOFeatures bits)
Set a specific IO feature.
Definition: TIOFeatures.cxx:139
Printf
void Printf(const char *fmt,...)
ROOT::TIOFeatures::GetFeatures
UChar_t GetFeatures() const
Definition: TIOFeatures.cxx:250
TBasket::EIOBits
EIOBits
Definition: TBasket.h:95
TClass
Definition: TClass.h:80
UChar_t
unsigned char UChar_t
Definition: RtypesCore.h:38
ROOT::TIOFeatures::fIOBits
UChar_t fIOBits
Definition: TIOFeatures.hxx:100
Class
void Class()
Definition: Class.C:29
ROOT
VSD Structures.
Definition: StringConv.hxx:21
TBasket.h
TBasket::EIOBits::kSupported
@ kSupported
Error
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:188
TError.h