// ///////////////////////////////////////////////////////////////////
//
//  File:      TFNameSelect.cpp
//
//  Version:   1.0
//
//  Author:    Reiner Rohlfs (GADC)
//
//  History:   1.0   08.08.03  first released version
//
// ///////////////////////////////////////////////////////////////////
#include <stdlib.h>

#include "TFGroup.h"

ClassImp(TFToken)
ClassImp(TFNameSelector)

//_____________________________________________________________________________
// TFToken:
//    TFToken is a class used by TFNameSelector and should not directly used by 
//    an application macro.
//
// TFNameSelector
//    The TFNameSelector class can be used to select elements (TFIOElement) in 
//    a TFGroup depending on the name of the elements: Create a group iterator 
//    ( TFGroup::MakeIter() ) and pass one ore more TFNameSelectors to this 
//    iterator ( TFGroupIterator::SetSelector() ) before any call to the 
//    function TFGroupIterator::Next(). Now Next() will "move" the iterator only
//    to TFIOElements that pass the selection criteria. 
//
//    One or more names have to be passed to the constructor of the TFNameSelector.
//    The names can include none, one or several "*" as a placeholder for any 
//    sub-string. The selector will pass element names that matches one of these 
//    names.
//
//    If more than one TFSelector is passed to a group iterator only elements 
//    that pass every selector will be returned. 
//    If one TFNameSelector has more than one name (second constructor) an 
//    element will pass this selector if one of these names matches the name of 
//    the element.

TFNameSelector::TFNameSelector(const char * name)
{
// Constructor for one name. name can include "*".
   fNumNames = 1;
   fNames = new TFToken[1];
   fNames->SetName(name);
}
//_____________________________________________________________________________
TFNameSelector::TFNameSelector(const char ** names, UInt_t numNames)
{
// Constructor for one or more names. names can include "*".
   fNumNames = numNames;
   fNames = new TFToken[fNumNames];

   for (UInt_t nm = 0; nm < numNames; nm++)
      (fNames+nm)->SetName(names[nm]);
}
//_____________________________________________________________________________
TFNameSelector::~TFNameSelector()
{
   delete [] fNames;
}
//_____________________________________________________________________________
Bool_t TFNameSelector::Select(TFElementPtr & item) const
{
// This function is used by the TFGroupIter to test if a element should
// be returned by the operator *() and operator ->()
 
   for (UInt_t nm = 0; nm < fNumNames; nm++)
      if ( (fNames+nm)->Select(item.GetElementName()) )
         return kTRUE;

   return kFALSE;            
}
//_____________________________________________________________________________
//_____________________________________________________________________________
TFToken::TFToken()
{
   fBuffer     = NULL;
   fToken      = NULL;
   fNumToken   = 0;
}
//_____________________________________________________________________________
TFToken::~TFToken()
{
   delete [] fBuffer;
   delete [] fToken;
}
//_____________________________________________________________________________
void TFToken::SetName(const char * name)
{
// Set the name for this token
   size_t   length = strlen(name);

   fBuffer = new char[length +1];
   strcpy(fBuffer, name);

   fLead = name[0] == '*';
   fTrail = length > 0 && name[length -1] == '*';
   UInt_t num = 2;
   while (*name)
      {
      if (*name == '*') num++;
      name++;
      }
   fToken = new char* [num];

   for (fNumToken = 0; ; fNumToken++)
      if ( (fToken[fNumToken] = strtok(fNumToken ? NULL : fBuffer, "*")) == NULL)
         break;
}
//_____________________________________________________________________________
Bool_t TFToken::Select(const char * testName)
{
// Tests if testName matches the name passed by the function SetName()
   if (fNumToken == 0)
      {
      if (fLead || fTrail) 
         return kTRUE;        // ie, only '*'
      else
         return kFALSE;       // empty test tring
      }

   const char * pos1, * pos2;

   pos1 = testName;
   for (UInt_t num = 0; num < fNumToken; num++)
      {
      if (!fTrail && num == fNumToken -1)
         {
         if (strlen(fToken[num]) > strlen(pos1))
            return kFALSE;
         pos1 = testName + strlen(testName) - strlen(fToken[num]);
         }
      if ((pos2 = strstr(pos1, fToken[num])) == NULL)
         return kFALSE;

      if (!fLead && num == 0 && pos1 != pos2)
         return kFALSE;       // 1.  token must start at 1. char
      
      pos1 = pos2 + strlen(fToken[num]);
      }

   return kTRUE;
}
//_____________________________________________________________________________

Last update: Fri Mar 14 13:55:22 2008

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.