Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.7

Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

DirectoryEnumerator.hpp

Go to the documentation of this file.
00001 /*
00002  * The Apache Software License, Version 1.1
00003  *
00004  *
00005  * Copyright (c) 1999-2004 The Apache Software Foundation.  All rights 
00006  * reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer. 
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in
00017  *    the documentation and/or other materials provided with the
00018  *    distribution.
00019  *
00020  * 3. The end-user documentation included with the redistribution,
00021  *    if any, must include the following acknowledgment:  
00022  *       "This product includes software developed by the
00023  *        Apache Software Foundation (http://www.apache.org/)."
00024  *    Alternately, this acknowledgment may appear in the software itself,
00025  *    if and wherever such third-party acknowledgments normally appear.
00026  *
00027  * 4. The names "Xalan" and "Apache Software Foundation" must
00028  *    not be used to endorse or promote products derived from this
00029  *    software without prior written permission. For written 
00030  *    permission, please contact apache@apache.org.
00031  *
00032  * 5. Products derived from this software may not be called "Apache",
00033  *    nor may "Apache" appear in their name, without prior written
00034  *    permission of the Apache Software Foundation.
00035  *
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00039  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00040  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00041  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00042  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00043  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00044  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00045  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00046  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00047  * SUCH DAMAGE.
00048  * ====================================================================
00049  *
00050  * This software consists of voluntary contributions made by many
00051  * individuals on behalf of the Apache Software Foundation and was
00052  * originally based on software copyright (c) 1999, International
00053  * Business Machines, Inc., http://www.ibm.com.  For more
00054  * information on the Apache Software Foundation, please see
00055  * <http://www.apache.org/>.
00056  */
00057 #if !defined(DIRECTORY_ENUMERATOR_HEADER_GUARD_1357924680)
00058 #define DIRECTORY_ENUMERATOR_HEADER_GUARD_1357924680
00059 
00060 
00061 
00062 // Base header file.  Must be first.
00063 #include <xalanc/PlatformSupport/PlatformSupportDefinitions.hpp>
00064 
00065 
00066 
00067 #if defined(_MSC_VER)
00068 #include <io.h>
00069 #else
00070 #include <dirent.h>
00071 #endif
00072 
00073 
00074 
00075 #include <functional>
00076 #include <iterator>
00077 
00078 
00079 
00080 #include <xalanc/PlatformSupport/DOMStringHelper.hpp>
00081 #include <xalanc/PlatformSupport/XalanUnicode.hpp>
00082 
00083 
00084 
00085 XALAN_CPP_NAMESPACE_BEGIN
00086 
00087 
00088 
00089 #if defined(_MSC_VER)
00090 
00091 struct FindFileStruct : public _wfinddata_t
00092 {
00093 
00094     enum eAttributes
00095     {
00096         eAttributeArchive = _A_ARCH,
00097         eAttributeDirectory = _A_SUBDIR,
00098         eAttributeHidden = _A_HIDDEN,
00099         eAttributeNormal = _A_NORMAL,
00100         eReadOnly = _A_RDONLY,
00101         eSystem = _A_SYSTEM
00102     };
00103 
00104 public:
00105 
00111     const XalanDOMChar*
00112     getName() const
00113     {
00114         return name;
00115     }
00116 
00122     bool
00123     isDirectory() const
00124     {
00125         return attrib & eAttributeDirectory ? true : false;
00126     }
00127 
00128     bool
00129     isSelfOrParent() const
00130     {
00131         if (isDirectory() == false)
00132         {
00133             return false;
00134         }
00135         else if (name[0] == '.')
00136         {
00137             if (name[1] == '\0')
00138             {
00139                 return true;
00140             }
00141             else if (name[1] == '.' &&
00142                      name[2] == '\0')
00143             {
00144                 return true;
00145             }
00146             else
00147             {
00148                 return false;
00149             }
00150         }
00151         else
00152         {
00153             return false;
00154         }
00155     }
00156 };
00157 
00158 #else
00159 
00160 struct FindFileStruct : public dirent
00161 {
00162 public:
00163 
00169     const char* getName() const
00170     {
00171         return d_name;
00172     }
00173 
00179     bool isDirectory() const
00180     {
00181 #if defined(AIX) || defined(HPUX) || defined(SOLARIS) || defined(OS390) || defined(OS400) || defined(TRU64)
00182         return false;
00183 #else       
00184         if (d_type == DT_DIR || d_type == DT_UNKNOWN)
00185         {
00186             return true;
00187         }
00188         else
00189         {
00190             return false;
00191         }
00192 #endif      
00193     }
00194 
00195     bool
00196     isSelfOrParent() const
00197     {
00198 #if defined(AIX) || defined(HPUX) || defined(SOLARIS) || defined(OS390) || defined(OS400) || defined(TRU64)
00199         return false;
00200 #else       
00201         if (isDirectory() == false)
00202         {
00203             return false;
00204         }
00205         else if (d_name[0] == '.')
00206         {
00207             if (d_name[1] == '\0')
00208             {
00209                 return true;
00210             }
00211             else if (d_name[1] == '.' &&
00212                      d_name[2] == '\0')
00213             {
00214                 return true;
00215             }
00216             else
00217             {
00218                 return false;
00219             }
00220         }
00221         else
00222         {
00223             return false;
00224         }
00225 #endif
00226     }
00227 };
00228 
00229 #endif
00230 
00231 
00232 
00233 #if defined(XALAN_NO_STD_NAMESPACE)
00234 struct DirectoryFilterPredicate : public unary_function<FindFileStruct, bool>
00235 #else
00236 struct DirectoryFilterPredicate : public std::unary_function<FindFileStruct, bool>
00237 #endif
00238 {
00239     result_type
00240 	operator()(const argument_type&    theFindData) const
00241     {
00242         return theFindData.isDirectory();
00243     }
00244 };
00245 
00246 
00247 
00248 #if defined(XALAN_NO_STD_NAMESPACE)
00249 struct FilesOnlyFilterPredicate : public unary_function<FindFileStruct, bool>
00250 #else
00251 struct FilesOnlyFilterPredicate : public std::unary_function<FindFileStruct, bool>
00252 #endif
00253 {
00254     result_type
00255 	operator()(const argument_type&    theFindData) const
00256     {
00257         DirectoryFilterPredicate        theDirectoryPredicate;
00258 
00259         return !theDirectoryPredicate(theFindData);
00260                
00261     }
00262 };
00263 
00264 
00265 
00266 template<class OutputIteratorType,
00267          class FilterPredicateType,
00268          class StringType,
00269          class StringConversionFunction>
00270 void
00271 EnumerateDirectory(
00272             const StringType&           theFullSearchSpec,
00273             OutputIteratorType          theOutputIterator,
00274             FilterPredicateType         theFilterPredicate,
00275             StringConversionFunction    theConversionFunction,
00276 #if defined(XALAN_TEMPLATE_FUNCTION_NO_DEFAULT_PARAMETERS)
00277             bool                        fIncludeSelfAndParent)
00278 #else
00279             bool                        fIncludeSelfAndParent = false)
00280 #endif
00281 {
00282 #if defined(_MSC_VER)
00283     FindFileStruct      theFindData;
00284 
00285     long    theSearchHandle = _wfindfirst(const_cast<wchar_t*>(theConversionFunction(theFullSearchSpec)),
00286                                           &theFindData);
00287 
00288     if (theSearchHandle != -1)
00289     {
00290         try
00291         {
00292             do
00293             {
00294                 if ((fIncludeSelfAndParent == true || theFindData.isSelfOrParent() == false) &&
00295                     theFilterPredicate(theFindData) == true)
00296                 {
00297                     *theOutputIterator = StringType(theFindData.getName());
00298                 }
00299             }
00300             while(_wfindnext(theSearchHandle,
00301                              &theFindData) == 0);
00302         }
00303         catch(...)
00304         {
00305             _findclose(theSearchHandle);
00306 
00307             throw;
00308         }
00309 
00310         _findclose(theSearchHandle);
00311     }
00312 
00313     
00314 #elif defined(LINUX)
00315 
00316     CharVectorType  theTargetVector;
00317 
00318     TranscodeToLocalCodePage(theFullSearchSpec, theTargetVector, false);
00319 
00320     const CharVectorType::size_type     theSize = theTargetVector.size();
00321 
00322     if (theSize > 0)
00323     {
00324         if (theTargetVector.back() == '*')
00325         {
00326             theTargetVector.pop_back();
00327 
00328             if (theSize == 1)
00329             {
00330                 theTargetVector.push_back('.');
00331             }
00332         }
00333 
00334         theTargetVector.push_back('\0');
00335 
00336         const char* const   theSpec = c_str(theTargetVector);
00337         assert(theSpec != 0);
00338 
00339         DIR* const  theDirectory = opendir(theSpec);
00340 
00341         if (theDirectory != 0)
00342         {
00343             try
00344             {
00345                 const FindFileStruct*   theEntry =
00346                     (FindFileStruct*)readdir(theDirectory);
00347     
00348                 while(theEntry != 0)
00349                 {
00350                     if ((fIncludeSelfAndParent == true || theEntry->isSelfOrParent() == false) &&
00351                         theFilterPredicate(*theEntry) == true)
00352                     {
00353                         *theOutputIterator = StringType(theEntry->getName());
00354                     }
00355 
00356                     theEntry = (FindFileStruct*)readdir(theDirectory);
00357                 }
00358             }
00359             catch(...)
00360             {
00361                 closedir(theDirectory);
00362 
00363                 throw;
00364             }
00365 
00366             closedir(theDirectory);
00367         }
00368     }
00369 #else
00370     // Do nothing for now...
00371     // Unsupported platform!!!
00372 #endif
00373 }
00374 
00375 
00376 
00377 template<class OutputIteratorType,
00378          class FilterPredicateType,
00379          class StringType,
00380          class StringConversionFunction>
00381 void
00382 EnumerateDirectory(
00383             const StringType&           theDirectory,
00384             const StringType&           theSearchSpec,
00385             OutputIteratorType          theOutputIterator,
00386             FilterPredicateType         theFilterPredicate,
00387             StringConversionFunction    theConversionFunction,
00388 #if defined(XALAN_TEMPLATE_FUNCTION_NO_DEFAULT_PARAMETERS)
00389             bool                        fIncludeSelfAndParent)
00390 #else
00391             bool                        fIncludeSelfAndParent = false)
00392 #endif
00393 {
00394     StringType  theFullSearchSpec(theDirectory);
00395 
00396     theFullSearchSpec += theSearchSpec;
00397 
00398     EnumerateDirectory(theFullSearchSpec, theOutputIterator, theFilterPredicate, theConversionFunction, fIncludeSelfAndParent);
00399 }
00400 
00401 
00402 
00403 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
00404 template<class CollectionType, class StringType>
00405 struct DirectoryEnumeratorFunctor
00406 {
00407     CollectionType
00408 	operator()(const StringType&   theDirectory) const
00409     {
00410         CollectionType      theCollection;
00411 
00412 		operator()(theDirectory,
00413                theCollection);
00414 
00415         return theCollection;
00416     }
00417 
00418     void
00419 	operator()(
00420         const StringType&,
00421         const CollectionType&) const
00422     {
00423     }
00424 };
00425 #else
00426 template<class CollectionType,
00427      class StringType = XalanDOMString,
00428      class FilterPredicateType = FilesOnlyFilterPredicate,
00429      class StringConversionFunction = c_wstr_functor>
00430 #if defined(XALAN_NO_STD_NAMESPACE)
00431 struct DirectoryEnumeratorFunctor : public unary_function<StringType, CollectionType>
00432 #else
00433 struct DirectoryEnumeratorFunctor : public std::unary_function<StringType, CollectionType>
00434 #endif
00435 {
00436 #if defined(XALAN_NO_STD_NAMESPACE)
00437     typedef unary_function<StringType, CollectionType>  BaseClassType;
00438 #else
00439     typedef std::unary_function<StringType, CollectionType> BaseClassType;
00440 #endif
00441 
00442     typedef typename BaseClassType::result_type     result_type;
00443     typedef typename BaseClassType::argument_type   argument_type;
00444 
00445     explicit
00446     DirectoryEnumeratorFunctor(bool     fIncludeSelfAndParent = false) :
00447         m_includeSelfAndParent(fIncludeSelfAndParent)
00448     {
00449     }
00450             
00451     void
00452 	operator()(
00453             const argument_type&    theFullSearchSpec,
00454             CollectionType&         theCollection) const
00455     {
00456         XALAN_USING_STD(back_inserter)
00457 
00458         EnumerateDirectory(
00459                 theFullSearchSpec,
00460                 XALAN_STD_QUALIFIER back_inserter(theCollection),
00461                 m_filterPredicate,
00462                 m_conversionFunction,
00463                 m_includeSelfAndParent);
00464     }
00465 
00466     result_type
00467 	operator()(const argument_type&        theFullSearchSpec) const
00468     {
00469         result_type     theCollection;
00470 
00471 		operator()(
00472                 theFullSearchSpec,
00473                 theCollection);
00474 
00475         return theCollection;
00476     }
00477 
00478     void
00479 	operator()(
00480             const argument_type&    theDirectory,
00481             const argument_type&    theSearchSpec,
00482             CollectionType&         theCollection) const
00483     {
00484         EnumerateDirectory(
00485                 theDirectory,
00486                 theSearchSpec,
00487                 XALAN_STD_QUALIFIER back_inserter(theCollection),
00488                 m_filterPredicate,
00489                 m_conversionFunction,
00490                 m_includeSelfAndParent);
00491     }
00492 
00493     result_type
00494 	operator()(
00495             const argument_type&    theDirectory,
00496             const argument_type&    theSearchSpec) const
00497     {
00498         result_type     theCollection;
00499 
00500 		operator()(
00501                 theDirectory,
00502                 theSearchSpec,
00503                 theCollection);
00504 
00505         return theCollection;
00506     }
00507 
00508 private:
00509 
00510     FilterPredicateType         m_filterPredicate;
00511 
00512     StringConversionFunction    m_conversionFunction;
00513 
00514     const bool                  m_includeSelfAndParent;
00515 };
00516 #endif
00517 
00518 
00519 
00520 XALAN_CPP_NAMESPACE_END
00521 
00522 
00523 
00524 #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.7
Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.