19 ClassImp(TSchemaRule);
22 using namespace ROOT::Detail;
27 TSchemaRuleSet::TSchemaRuleSet(): fPersistentRules( 0 ), fRemainingRules( 0 ),
28 fAllRules( 0 ), fVersion(-3), fCheckSum( 0 )
30 fPersistentRules =
new TObjArray();
31 fRemainingRules =
new TObjArray();
32 fAllRules =
new TObjArray();
33 fAllRules->SetOwner( kTRUE );
39 TSchemaRuleSet::~TSchemaRuleSet()
41 delete fPersistentRules;
42 delete fRemainingRules;
50 void TSchemaRuleSet::ls(Option_t *)
const
53 std::cout <<
"TSchemaRuleSet for " << fClassName <<
":\n";
54 TROOT::IncreaseDirLevel();
56 TIter next(fPersistentRules);
57 while ((
object = next())) {
58 object->ls(fClassName);
60 TROOT::DecreaseDirLevel();
65 Bool_t TSchemaRuleSet::AddRules( TSchemaRuleSet* , EConsistencyCheck , TString * )
80 Bool_t TSchemaRuleSet::AddRule( TSchemaRule* rule, EConsistencyCheck checkConsistency, TString *errmsg )
86 if( (checkConsistency != kNoCheck) && !fClass )
89 if( !rule->IsValid() )
96 if( checkConsistency == kNoCheck ) {
97 if( rule->GetEmbed() )
98 fPersistentRules->Add( rule );
100 fRemainingRules->Add( rule );
101 fAllRules->Add( rule );
112 bool streamerInfosTest;
114 R__LOCKGUARD(gInterpreterMutex);
115 streamerInfosTest = (fClass->GetStreamerInfos()==0 || fClass->GetStreamerInfos()->GetEntries()==0);
117 if( rule->GetTarget() && !(fClass->TestBit(TClass::kIsEmulation) && streamerInfosTest) ) {
118 TObjArrayIter titer( rule->GetTarget() );
120 while( (obj = titer.Next()) ) {
121 TObjString* str = (TObjString*)obj;
122 if( !fClass->GetDataMember( str->GetString() ) && !fClass->GetBaseClass( str->GetString() ) ) {
123 if (checkConsistency == kCheckAll) {
125 errmsg->Form(
"the target member (%s) is unknown",str->GetString().Data());
141 std::vector<const TSchemaRule*> rules = FindRules( rule->GetSourceClass() );
145 for(
auto r : rules) {
146 if( rule->Conflicts( r ) ) {
152 *errmsg =
"it conflicts with one of the other rules";
158 *errmsg =
"The existing rule is:\n ";
159 r->AsString(*errmsg,
"s");
160 *errmsg +=
"\nand the ignored rule is:\n ";
161 rule->AsString(*errmsg);
172 if( rule->GetEmbed() )
173 fPersistentRules->Add( rule );
175 fRemainingRules->Add( rule );
176 fAllRules->Add( rule );
184 void TSchemaRuleSet::AsString(TString &out)
const
186 TObjArrayIter it( fAllRules );
188 while( (rule = (TSchemaRule*)it.Next()) ) {
197 Bool_t TSchemaRuleSet::HasRuleWithSourceClass(
const TString &source )
const
199 TObjArrayIter it( fAllRules );
201 while( (obj = it.Next()) ) {
202 TSchemaRule* rule = (TSchemaRule*)obj;
203 if( rule->GetSourceClass() == source )
207 if (fClass->GetCollectionProxy()) {
208 if (fClass->GetCollectionProxy()->GetValueClass() == 0) {
211 TClass *src = TClass::GetClass(source);
212 if (src && src->GetCollectionProxy() &&
213 src->GetCollectionProxy()->HasPointers() == fClass->GetCollectionProxy()->HasPointers()) {
214 TVirtualCollectionProxy *proxy = src->GetCollectionProxy();
215 if (proxy->GetValueClass() == 0) {
220 TClass *vTargetClass = fClass->GetCollectionProxy()->GetValueClass();
221 TClass *src = TClass::GetClass(source);
222 if (vTargetClass->GetSchemaRules()) {
223 if (src && src->GetCollectionProxy() &&
224 src->GetCollectionProxy()->HasPointers() == fClass->GetCollectionProxy()->HasPointers()) {
225 TClass *vSourceClass = src->GetCollectionProxy()->GetValueClass();
227 return vTargetClass->GetSchemaRules()->HasRuleWithSourceClass( vSourceClass->GetName() );
232 }
else if (!strncmp(fClass->GetName(),
"std::pair<",10) || !strncmp(fClass->GetName(),
"pair<",5)) {
233 if (!strncmp(source,
"std::pair<",10) || !strncmp(source,
"pair<",5)) {
236 TClass *src = TClass::GetClass(source);
238 Error(
"HasRuleWithSourceClass",
"Can not find the TClass for %s when matching with %s\n",source.Data(),fClass->GetName());
241 TVirtualStreamerInfo *sourceInfo = src->GetStreamerInfo();
242 TVirtualStreamerInfo *targetInfo = fClass->GetStreamerInfo();
244 Error(
"HasRuleWithSourceClass",
"Can not find the StreamerInfo for %s when matching with %s\n",source.Data(),fClass->GetName());
248 Error(
"HasRuleWithSourceClass",
"Can not find the StreamerInfo for target class %s\n",fClass->GetName());
251 for(
int i = 0 ; i<2 ; ++i) {
252 TStreamerElement *sourceElement = (TStreamerElement*)sourceInfo->GetElements()->At(i);
253 TStreamerElement *targetElement = (TStreamerElement*)targetInfo->GetElements()->At(i);
254 if (sourceElement->GetClass()) {
255 if (!targetElement->GetClass()) {
258 if (sourceElement->GetClass() == targetElement->GetClass()) {
261 TSchemaRuleSet *rules = sourceElement->GetClass()->GetSchemaRules();
262 if (!rules || !rules->HasRuleWithSourceClass( targetElement->GetClass()->GetName() ) ) {
265 }
else if (targetElement->GetClass()) {
272 ROOT::TSchemaRule *ruleobj =
new ROOT::TSchemaRule();
273 ruleobj->SetSourceClass(source);
274 ruleobj->SetTargetClass(fClass->GetName());
275 ruleobj->SetVersion(
"[1-]");
276 const_cast<TSchemaRuleSet*
>(
this)->AddRule(ruleobj);
287 const TSchemaRuleSet::TMatches TSchemaRuleSet::FindRules(
const TString &source )
const
290 TObjArrayIter it( fAllRules );
294 while( (obj = it.Next()) ) {
295 TSchemaRule* rule = (TSchemaRule*)obj;
296 if( rule->GetSourceClass() == source )
297 arr.push_back( rule );
302 if (fClass->GetCollectionProxy()) {
303 if (fClass->GetCollectionProxy()->GetValueClass() == 0
304 && (fClass->GetCollectionProxy()->GetCollectionType() == TClassEdit::kVector
305 || (fClass->GetCollectionProxy()->GetProperties() & TVirtualCollectionProxy::kIsEmulated))) {
308 TClass *src = TClass::GetClass(source);
309 if (src && src->GetCollectionProxy()) {
310 TVirtualCollectionProxy *proxy = src->GetCollectionProxy();
311 if (proxy->GetValueClass() == 0) {
326 const TSchemaRuleSet::TMatches TSchemaRuleSet::FindRules(
const TString &source, Int_t version )
const
329 TObjArrayIter it( fAllRules );
333 while( (obj = it.Next()) ) {
334 TSchemaRule* rule = (TSchemaRule*)obj;
335 if( rule->GetSourceClass() == source && rule->TestVersion( version ) )
336 arr.push_back( rule );
346 const TSchemaRuleSet::TMatches TSchemaRuleSet::FindRules(
const TString &source, UInt_t checksum )
const
349 TObjArrayIter it( fAllRules );
353 while( (obj = it.Next()) ) {
354 TSchemaRule* rule = (TSchemaRule*)obj;
355 if( rule->GetSourceClass() == source && rule->TestChecksum( checksum ) )
356 arr.push_back( rule );
366 const TSchemaRuleSet::TMatches TSchemaRuleSet::FindRules(
const TString &source, Int_t version, UInt_t checksum )
const
369 TObjArrayIter it( fAllRules );
373 while( (obj = it.Next()) ) {
374 TSchemaRule* rule = (TSchemaRule*)obj;
375 if( rule->GetSourceClass() == source && ( rule->TestVersion( version ) || rule->TestChecksum( checksum ) ) )
376 arr.push_back( rule );
384 TClass* TSchemaRuleSet::GetClass()
391 UInt_t TSchemaRuleSet::GetClassCheckSum()
const
393 if (fCheckSum == 0 && fClass) {
394 const_cast<TSchemaRuleSet*
>(
this)->fCheckSum = fClass->GetCheckSum();
401 TString TSchemaRuleSet::GetClassName()
const
408 Int_t TSchemaRuleSet::GetClassVersion()
const
415 const TObjArray* TSchemaRuleSet::GetRules()
const
422 const TObjArray* TSchemaRuleSet::GetPersistentRules()
const
424 return fPersistentRules;
430 void TSchemaRuleSet::RemoveRule( TSchemaRule* rule )
432 fPersistentRules->Remove( rule );
433 fRemainingRules->Remove( rule );
434 fAllRules->Remove( rule );
440 void TSchemaRuleSet::RemoveRules( TObjArray* rules )
443 TObjArrayIter it( rules );
445 while( (obj = it.Next()) ) {
446 fPersistentRules->Remove( obj );
447 fRemainingRules->Remove( obj );
448 fAllRules->Remove( obj );
455 void TSchemaRuleSet::SetClass( TClass* cls )
458 fClassName = cls->GetName();
459 fVersion = cls->GetClassVersion();
466 const TSchemaRule* TSchemaRuleSet::TMatches::GetRuleWithSource(
const TString& name )
const
468 for(
auto rule : *
this ) {
469 if( rule->HasSource( name ) )
return rule;
477 const TSchemaRule* TSchemaRuleSet::TMatches::GetRuleWithTarget(
const TString& name )
const
479 for(
auto rule : *
this ) {
480 if( rule->HasTarget( name ) )
return rule;
491 Bool_t TSchemaRuleSet::TMatches::HasRuleWithSource(
const TString& name, Bool_t needingAlloc )
const
493 for(
auto rule : *
this ) {
494 if( rule->HasSource( name ) ) {
496 const TObjArray *targets = rule->GetTarget();
497 if (targets && (targets->GetEntries() > 1 || targets->GetEntries()==0) ) {
500 if (targets && name != targets->UncheckedAt(0)->GetName() ) {
505 if (rule->GetReadFunctionPointer() || rule->GetReadRawFunctionPointer()) {
521 Bool_t TSchemaRuleSet::TMatches::HasRuleWithTarget(
const TString& name, Bool_t willset )
const
523 for(
auto rule : *
this) {
524 if( rule->HasTarget( name ) ) {
526 const TObjArray *targets = rule->GetTarget();
527 if (targets && (targets->GetEntries() > 1 || targets->GetEntries()==0) ) {
530 const TObjArray *sources = rule->GetSource();
531 if (sources && (sources->GetEntries() > 1 || sources->GetEntries()==0) ) {
534 if (sources && name != sources->UncheckedAt(0)->GetName() ) {
539 if (rule->GetReadFunctionPointer() || rule->GetReadRawFunctionPointer()) {
553 void TSchemaRuleSet::Streamer(TBuffer &R__b)
555 if (R__b.IsReading()) {
556 R__b.ReadClassBuffer(ROOT::Detail::TSchemaRuleSet::Class(),
this);
558 fAllRules->AddAll(fPersistentRules);
561 R__b.WriteClassBuffer(ROOT::Detail::TSchemaRuleSet::Class(),
this);