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