Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.9

Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

DirectoryEnumerator.hpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 1999-2004 The Apache Software Foundation.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #if !defined(DIRECTORY_ENUMERATOR_HEADER_GUARD_1357924680)
00017 #define DIRECTORY_ENUMERATOR_HEADER_GUARD_1357924680
00018 
00019 
00020 
00021 // Base header file.  Must be first.
00022 #include <xalanc/PlatformSupport/PlatformSupportDefinitions.hpp>
00023 
00024 
00025 
00026 #if defined(_MSC_VER)
00027 #include <io.h>
00028 #else
00029 #include <unistd.h>
00030 #include <dirent.h>
00031 #include <sys/stat.h>
00032 #include <errno.h>
00033 
00034 extern int  errno;
00035 
00036 #endif
00037 
00038 
00039 
00040 #include <functional>
00041 #include <iterator>
00042 
00043 
00044 #include <xalanc/PlatformSupport/XalanFileOutputStream.hpp>
00045 #include <xalanc/PlatformSupport/DOMStringHelper.hpp>
00046 #include <xalanc/PlatformSupport/XalanUnicode.hpp>
00047 
00048 
00049 
00050 XALAN_CPP_NAMESPACE_BEGIN
00051 
00052 
00053 
00054 #if defined(_MSC_VER)
00055 
00056 struct FindFileStruct : public _wfinddata_t
00057 {
00058 
00059     enum eAttributes
00060     {
00061         eAttributeArchive = _A_ARCH,
00062         eAttributeDirectory = _A_SUBDIR,
00063         eAttributeHidden = _A_HIDDEN,
00064         eAttributeNormal = _A_NORMAL,
00065         eReadOnly = _A_RDONLY,
00066         eSystem = _A_SYSTEM
00067     };
00068 
00069 public:
00070 
00076     const XalanDOMChar*
00077     getName() const
00078     {
00079         return name;
00080     }
00081 
00087     bool
00088     isDirectory() const
00089     {
00090         return attrib & eAttributeDirectory ? true : false;
00091     }
00092 
00093     bool
00094     isSelfOrParent() const
00095     {
00096         if (isDirectory() == false)
00097         {
00098             return false;
00099         }
00100         else if (name[0] == '.')
00101         {
00102             if (name[1] == '\0')
00103             {
00104                 return true;
00105             }
00106             else if (name[1] == '.' &&
00107                      name[2] == '\0')
00108             {
00109                 return true;
00110             }
00111             else
00112             {
00113                 return false;
00114             }
00115         }
00116         else
00117         {
00118             return false;
00119         }
00120     }
00121 };
00122 
00123 #else
00124 
00125 struct FindFileStruct : public dirent
00126 {
00127 public:
00128 
00134     const char* getName() const
00135     {
00136         return d_name;
00137     }
00138 
00144     bool isDirectory() const
00145     {
00146 
00147         struct  stat stat_Info;
00148         int retCode = stat (d_name, &stat_Info);
00149  
00150         if ( retCode == -1 )
00151         {
00152             XalanDOMString theBuffer(XalanMemMgrs::getDefaultXercesMemMgr());
00153             typedef XalanFileOutputStream::XalanFileOutputStreamOpenException XalanStatDirectoryException;
00154             throw   XalanStatDirectoryException( XalanDOMString(d_name, XalanMemMgrs::getDefaultXercesMemMgr()), errno , theBuffer);
00155         }
00156 
00157         return S_ISDIR(stat_Info.st_mode);
00158         
00159     }
00160 
00161     bool
00162     isSelfOrParent() const
00163     {       
00164         if (isDirectory() == false)
00165         {
00166             return false;
00167         }
00168         else if (d_name[0] == '.')
00169         {
00170             if (d_name[1] == '\0')
00171             {
00172                 return true;
00173             }
00174             else if (d_name[1] == '.' &&
00175                      d_name[2] == '\0')
00176             {
00177                 return true;
00178             }
00179             else
00180             {
00181                 return false;
00182             }
00183         }
00184         else
00185         {
00186             return false;
00187         }
00188     }
00189 };
00190 
00191 #endif
00192 
00193 
00194 
00195 #if defined(XALAN_NO_STD_NAMESPACE)
00196 struct DirectoryFilterPredicate : public unary_function<FindFileStruct, bool>
00197 #else
00198 struct DirectoryFilterPredicate : public std::unary_function<FindFileStruct, bool>
00199 #endif
00200 {
00201     result_type
00202     operator()(const argument_type& theFindData) const
00203     {
00204         return theFindData.isDirectory();
00205     }
00206 };
00207 
00208 
00209 
00210 #if defined(XALAN_NO_STD_NAMESPACE)
00211 struct FilesOnlyFilterPredicate : public unary_function<FindFileStruct, bool>
00212 #else
00213 struct FilesOnlyFilterPredicate : public std::unary_function<FindFileStruct, bool>
00214 #endif
00215 {
00216     result_type
00217     operator()(const argument_type& theFindData) const
00218     {
00219         DirectoryFilterPredicate        theDirectoryPredicate;
00220 
00221         return !theDirectoryPredicate(theFindData);
00222                
00223     }
00224 };
00225 
00226 
00227 
00228 template<class OutputIteratorType,
00229          class FilterPredicateType,
00230          class StringType,
00231          class StringConversionFunction>
00232 void
00233 EnumerateDirectory(
00234             const StringType&           theFullSearchSpec,
00235             OutputIteratorType          theOutputIterator,
00236             FilterPredicateType         theFilterPredicate,
00237             StringConversionFunction    theConversionFunction,
00238 #if defined(XALAN_TEMPLATE_FUNCTION_NO_DEFAULT_PARAMETERS)
00239             bool                        fIncludeSelfAndParent)
00240 #else
00241             bool                        fIncludeSelfAndParent = false)
00242 #endif
00243 {
00244     MemoryManagerType& theManager = XalanMemMgrs::getDefaultXercesMemMgr();
00245 #if defined(_MSC_VER)
00246     FindFileStruct      theFindData;
00247     
00248     #ifdef _WIN64
00249         typedef intptr_t    theHandleType;
00250     #else
00251         typedef long    theHandleType;
00252     #endif
00253 
00254 #pragma warning(push)
00255 #pragma warning(disable: 4244)
00256     theHandleType   theSearchHandle = _wfindfirst(const_cast<wchar_t*>(theConversionFunction(theFullSearchSpec)),
00257                                           &theFindData);
00258 #pragma warning(pop)
00259 
00260     if (theSearchHandle != -1)
00261     {
00262   
00263         try
00264         {
00265             do
00266             {
00267                 if ((fIncludeSelfAndParent == true || theFindData.isSelfOrParent() == false) &&
00268                     theFilterPredicate(theFindData) == true)
00269                 {
00270                     *theOutputIterator = StringType(theFindData.getName(), theManager);
00271                 }
00272             }
00273             while(_wfindnext(theSearchHandle,
00274                              &theFindData) == 0);
00275         }
00276         catch(...)
00277         {
00278             _findclose(theSearchHandle);
00279 
00280             throw;
00281         }
00282 
00283         _findclose(theSearchHandle);
00284     }
00285 
00286 
00287 #else   
00288 
00289     CharVectorType  theTargetVector(theManager);
00290 
00291     TranscodeToLocalCodePage(theFullSearchSpec, theTargetVector, false);
00292 
00293     const CharVectorType::size_type     theSize = theTargetVector.size();
00294     int  indexSuffix=0, indexName=0;
00295     bool target_Dir = false; 
00296 
00297     if (theSize > 0)
00298     {
00299         if (theTargetVector.back() == '*')
00300         {
00301             target_Dir = true;
00302             theTargetVector.pop_back();
00303 
00304             if (theSize == 1)
00305             {
00306                 theTargetVector.push_back('.');
00307             }
00308         
00309         }
00310         else
00311         {
00312             target_Dir = false;
00313 
00314             while(theTargetVector.back() != '*')
00315             {
00316                 theTargetVector.pop_back();
00317                 indexSuffix++;
00318             }
00319 
00320             theTargetVector.pop_back();
00321             while(theTargetVector.back() != '/')
00322             { 
00323                 theTargetVector.pop_back();
00324                 indexName++;
00325             }
00326         }      
00327 
00328         theTargetVector.push_back('\0');
00329 
00330         const char* const   theSpec = c_str(theTargetVector);
00331         assert(theSpec != 0);
00332         
00333         XalanDOMString      theName(theManager);
00334         XalanDOMString      theSuffix(theManager);
00335         if ( !target_Dir )
00336         {
00337 #if defined(XALAN_STRICT_ANSI_HEADERS)
00338             using std::strlen;
00339 #endif
00340 
00341             int lenSpec = strlen(theSpec); 
00342             theFullSearchSpec.substr(theName, lenSpec, indexName); 
00343             theFullSearchSpec.substr(theSuffix, lenSpec+indexName+1, indexSuffix);
00344         }
00345 
00346         DIR* const  theDirectory = opendir(theSpec);
00347 
00348         if (theDirectory != 0)
00349         {
00350             chdir(theSpec);
00351             try
00352             {
00353                 const FindFileStruct*   theEntry =
00354                     (FindFileStruct*)readdir(theDirectory);
00355     
00356                 while(theEntry != 0)
00357                 {
00358                     if ((fIncludeSelfAndParent == true || theEntry->isSelfOrParent() == false))
00359                     {
00360                         if (theFilterPredicate(*theEntry) == true)
00361                         {
00362                             if( target_Dir )
00363                             {
00364                                 *theOutputIterator = StringType(theEntry->getName(), theManager);
00365                             }
00366                             else
00367                             {
00368                                 XalanDOMString  Getname(theEntry->getName(), theManager);
00369                                 int Check_1 = Getname.compare(theName);
00370                                 XalanDOMString  GetnameSuffix(theManager);
00371                                 Getname.substr(GetnameSuffix, Getname.size() -indexSuffix, indexSuffix);            
00372                                 int Check_2 = GetnameSuffix.compare(theSuffix);
00373                                 if ( Check_1 == 1 && (!Check_2) )
00374                                 {
00375                                 *theOutputIterator = StringType(theEntry->getName(), theManager);
00376                                 }
00377                             }
00378                         }
00379                     }
00380                     theEntry = (FindFileStruct*)readdir(theDirectory);
00381                 } //while
00382             }//try
00383 
00384             catch(...)
00385             {
00386                 closedir(theDirectory);
00387 
00388                 throw;
00389             }
00390             if( target_Dir )
00391                            chdir("..");
00392                          else
00393                            chdir("../..");
00394             closedir(theDirectory);
00395         }
00396     }
00397 
00398 #endif
00399 }
00400 
00401 
00402 
00403 template<class OutputIteratorType,
00404          class FilterPredicateType,
00405          class StringType,
00406          class StringConversionFunction>
00407 void
00408 EnumerateDirectory(
00409             const StringType&           theDirectory,
00410             const StringType&           theSearchSpec,
00411             OutputIteratorType          theOutputIterator,
00412             FilterPredicateType         theFilterPredicate,
00413             StringConversionFunction    theConversionFunction,
00414 #if defined(XALAN_TEMPLATE_FUNCTION_NO_DEFAULT_PARAMETERS)
00415             bool                        fIncludeSelfAndParent)
00416 #else
00417             bool                        fIncludeSelfAndParent = false)
00418 #endif
00419 {
00420     MemoryManagerType& theManager = XalanMemMgrs::getDefaultXercesMemMgr();
00421 
00422     StringType  theFullSearchSpec(theDirectory, theManager);
00423 
00424     theFullSearchSpec += theSearchSpec;
00425 
00426     EnumerateDirectory(theFullSearchSpec, theOutputIterator, theFilterPredicate, theConversionFunction, fIncludeSelfAndParent);
00427 }
00428 
00429 
00430 
00431 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
00432 template<class CollectionType, class StringType>
00433 struct DirectoryEnumeratorFunctor
00434 {
00435     CollectionType
00436     operator()(const StringType&    theDirectory) const
00437     {
00438         CollectionType      theCollection;
00439 
00440         operator()(theDirectory,
00441                theCollection);
00442 
00443         return theCollection;
00444     }
00445 
00446     void
00447     operator()(
00448         const StringType&,
00449         const CollectionType&) const
00450     {
00451     }
00452 };
00453 #else
00454 template<class CollectionType,
00455      class StringType = XalanDOMString,
00456      class FilterPredicateType = FilesOnlyFilterPredicate,
00457      class StringConversionFunction = c_wstr_functor>
00458 #if defined(XALAN_NO_STD_NAMESPACE)
00459 struct DirectoryEnumeratorFunctor : public unary_function<StringType, CollectionType>
00460 #else
00461 struct DirectoryEnumeratorFunctor : public std::unary_function<StringType, CollectionType>
00462 #endif
00463 {
00464 #if defined(XALAN_NO_STD_NAMESPACE)
00465     typedef unary_function<StringType, CollectionType>  BaseClassType;
00466 #else
00467     typedef std::unary_function<StringType, CollectionType> BaseClassType;
00468 #endif
00469 
00470     typedef typename BaseClassType::result_type     result_type;
00471     typedef typename BaseClassType::argument_type   argument_type;
00472 
00473     explicit
00474     DirectoryEnumeratorFunctor(bool     fIncludeSelfAndParent = false) :
00475         m_includeSelfAndParent(fIncludeSelfAndParent)
00476     {
00477     }
00478             
00479     void
00480     operator()(
00481             const argument_type&    theFullSearchSpec,
00482             CollectionType&         theCollection) const
00483     {
00484         XALAN_USING_STD(back_inserter)
00485 
00486         EnumerateDirectory(
00487                 theFullSearchSpec,
00488                 XALAN_STD_QUALIFIER back_inserter(theCollection),
00489                 m_filterPredicate,
00490                 m_conversionFunction,
00491                 m_includeSelfAndParent);
00492     }
00493 
00494     result_type
00495     operator()(const argument_type&     theFullSearchSpec) const
00496     {
00497         result_type     theCollection;
00498 
00499         operator()(
00500                 theFullSearchSpec,
00501                 theCollection);
00502 
00503         return theCollection;
00504     }
00505 
00506     void
00507     operator()(
00508             const argument_type&    theDirectory,
00509             const argument_type&    theSearchSpec,
00510             CollectionType&         theCollection) const
00511     {
00512         EnumerateDirectory(
00513                 theDirectory,
00514                 theSearchSpec,
00515                 XALAN_STD_QUALIFIER back_inserter(theCollection),
00516                 m_filterPredicate,
00517                 m_conversionFunction,
00518                 m_includeSelfAndParent);
00519     }
00520 
00521     result_type
00522     operator()(
00523             const argument_type&    theDirectory,
00524             const argument_type&    theSearchSpec) const
00525     {
00526         result_type     theCollection;
00527 
00528         operator()(
00529                 theDirectory,
00530                 theSearchSpec,
00531                 theCollection);
00532 
00533         return theCollection;
00534     }
00535 
00536 private:
00537 
00538     FilterPredicateType         m_filterPredicate;
00539 
00540     StringConversionFunction    m_conversionFunction;
00541 
00542     const bool                  m_includeSelfAndParent;
00543 };
00544 #endif
00545 
00546 
00547 
00548 XALAN_CPP_NAMESPACE_END
00549 
00550 
00551 
00552 #endif  // DIRECTORY_ENUMERATOR_HEADER_GUARD_1357924680

Interpreting class diagrams

Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.

Xalan-C++ XSLT Processor Version 1.9
Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.