Xalan-C++ API Reference  1.12.0
DirectoryEnumerator.hpp
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 #if !defined(DIRECTORY_ENUMERATOR_HEADER_GUARD_1357924680)
19 #define DIRECTORY_ENUMERATOR_HEADER_GUARD_1357924680
20 
21 
22 
23 // Base header file. Must be first.
25 
26 
27 
28 #include <cstring>
29 #if defined(_MSC_VER)
30 #include <io.h>
31 #else
32 #include <dirent.h>
33 #include <errno.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36 #endif
37 
38 
39 
40 #include <functional>
41 #include <iterator>
42 
43 
44 #include "xercesc/framework/MemoryManager.hpp"
45 
46 
47 
51 
52 
53 
54 namespace XALAN_CPP_NAMESPACE {
55 
56 
57 
58 using xercesc::MemoryManager;
59 
60 
61 
62 #if defined(_MSC_VER)
63 
64 struct FindFileStruct : public _wfinddata_t
65 {
66 
67  enum eAttributes
68  {
69  eAttributeArchive = _A_ARCH,
70  eAttributeDirectory = _A_SUBDIR,
71  eAttributeHidden = _A_HIDDEN,
72  eAttributeNormal = _A_NORMAL,
73  eReadOnly = _A_RDONLY,
74  eSystem = _A_SYSTEM
75  };
76 
77 public:
78 
79  /**
80  * Retrieve name of file
81  *
82  * @return file name
83  */
84  const XalanDOMChar*
85  getName() const
86  {
87  return const_cast<XalanDOMChar*>(reinterpret_cast<const XalanDOMChar*>(&name[0]));
88  }
89 
90  /**
91  * Determine whether file is a directory
92  *
93  * @return true if file is a directory
94  */
95  bool
96  isDirectory() const
97  {
98  return attrib & eAttributeDirectory ? true : false;
99  }
100 
101  bool
102  isSelfOrParent() const
103  {
104  if (isDirectory() == false)
105  {
106  return false;
107  }
108  else if (name[0] == '.')
109  {
110  if (name[1] == '\0')
111  {
112  return true;
113  }
114  else if (name[1] == '.' &&
115  name[2] == '\0')
116  {
117  return true;
118  }
119  else
120  {
121  return false;
122  }
123  }
124  else
125  {
126  return false;
127  }
128  }
129 };
130 
131 #else
132 
133 struct FindFileStruct : public dirent
134 {
135 public:
136 
137  /**
138  * Retrieve name of file
139  *
140  * @return file name
141  */
142  const char* getName() const
143  {
144  return d_name;
145  }
146 
147  /**
148  * Determine whether file is a directory
149  *
150  * @return true if file is a directory
151  */
152  bool isDirectory() const
153  {
154 #if defined(__SunOS_5_10) && (__SUNPRO_CC >= 0x570)
155  struct stat64 stat_Info;
156 
157  const int retCode = stat64(d_name, &stat_Info);
158 #else
159  struct stat stat_Info;
160 
161  const int retCode = stat(d_name, &stat_Info);
162 #endif
163 
164  return retCode == -1 ? false : S_ISDIR(stat_Info.st_mode);
165  }
166 
167  bool
169  {
170  if (isDirectory() == false)
171  {
172  return false;
173  }
174  else if (d_name[0] == '.')
175  {
176  if (d_name[1] == '\0')
177  {
178  return true;
179  }
180  else if (d_name[1] == '.' &&
181  d_name[2] == '\0')
182  {
183  return true;
184  }
185  else
186  {
187  return false;
188  }
189  }
190  else
191  {
192  return false;
193  }
194  }
195 };
196 
197 #endif
198 
199 
200 
202 {
203  bool
204  operator()(const FindFileStruct& theFindData) const
205  {
206  return theFindData.isDirectory();
207  }
208 };
209 
210 
211 
213 {
214  bool
215  operator()(const FindFileStruct& theFindData) const
216  {
217  DirectoryFilterPredicate theDirectoryPredicate;
218 
219  return !theDirectoryPredicate(theFindData);
220 
221  }
222 };
223 
224 
225 
226 template<class OutputIteratorType,
227  class FilterPredicateType,
228  class StringType,
229  class StringConversionFunction>
230 void
232  MemoryManager& theMemoryManager,
233  const StringType& theFullSearchSpec,
234  OutputIteratorType theOutputIterator,
235  FilterPredicateType theFilterPredicate,
236  StringConversionFunction theConversionFunction,
237 #if defined(XALAN_TEMPLATE_FUNCTION_NO_DEFAULT_PARAMETERS)
238  bool fIncludeSelfAndParent)
239 #else
240  bool fIncludeSelfAndParent = false)
241 #endif
242 {
243 #if defined(_MSC_VER)
244  FindFileStruct theFindData;
245 
246  #ifdef _WIN64
247  typedef intptr_t theHandleType;
248  #else
249  typedef long theHandleType;
250  #endif
251 
252 #pragma warning(push)
253 #pragma warning(disable: 4244)
254  theHandleType theSearchHandle =
255  _wfindfirst(
256  reinterpret_cast<wchar_t*>(const_cast<XalanDOMChar*>(theConversionFunction(theFullSearchSpec))),
257  &theFindData);
258 #pragma warning(pop)
259 
260  if (theSearchHandle != -1)
261  {
262 
263  try
264  {
265  do
266  {
267  if ((fIncludeSelfAndParent == true || theFindData.isSelfOrParent() == false) &&
268  theFilterPredicate(theFindData) == true)
269  {
270  *theOutputIterator = StringType(theFindData.getName(), theMemoryManager);
271  }
272  }
273  while(_wfindnext(theSearchHandle,
274  &theFindData) == 0);
275  }
276  catch(...)
277  {
278  _findclose(theSearchHandle);
279 
280  throw;
281  }
282 
283  _findclose(theSearchHandle);
284  }
285 
286 
287 #else
288 
289  CharVectorType theTargetVector(theMemoryManager);
290 
291  TranscodeToLocalCodePage(theFullSearchSpec, theTargetVector, false);
292 
293  const CharVectorType::size_type theSize = theTargetVector.size();
294  int indexSuffix=0, indexName=0;
295  bool target_Dir = false;
296 
297  if (theSize > 0)
298  {
299  if (theTargetVector.back() == '*')
300  {
301  target_Dir = true;
302  theTargetVector.pop_back();
303 
304  if (theSize == 1)
305  {
306  theTargetVector.push_back('.');
307  }
308 
309  }
310  else
311  {
312  target_Dir = false;
313 
314  while(theTargetVector.back() != '*')
315  {
316  theTargetVector.pop_back();
317  indexSuffix++;
318  }
319 
320  theTargetVector.pop_back();
321  while(theTargetVector.back() != '/')
322  {
323  theTargetVector.pop_back();
324  indexName++;
325  }
326  }
327 
328  theTargetVector.push_back('\0');
329 
330  const char* const theSpec = c_str(theTargetVector);
331  assert(theSpec != 0);
332 
333  XalanDOMString theName(theMemoryManager);
334  XalanDOMString theSuffix(theMemoryManager);
335  if ( !target_Dir )
336  {
337  using std::strlen;
338 
339  int lenSpec = strlen(theSpec);
340  theFullSearchSpec.substr(theName, lenSpec, indexName);
341  theFullSearchSpec.substr(theSuffix, lenSpec+indexName+1, indexSuffix);
342  }
343 
344  DIR* const theDirectory = opendir(theSpec);
345 
346  if (theDirectory != 0)
347  {
348  chdir(theSpec);
349  try
350  {
351  const FindFileStruct* theEntry =
352  (FindFileStruct*)readdir(theDirectory);
353 
354  while(theEntry != 0)
355  {
356  if ((fIncludeSelfAndParent == true || theEntry->isSelfOrParent() == false))
357  {
358  if (theFilterPredicate(*theEntry) == true)
359  {
360  if( target_Dir )
361  {
362  *theOutputIterator = StringType(theEntry->getName(), theMemoryManager);
363  }
364  else
365  {
366  XalanDOMString Getname(theEntry->getName(), theMemoryManager);
367  int Check_1 = Getname.compare(theName);
368  XalanDOMString GetnameSuffix(theMemoryManager);
369  Getname.substr(GetnameSuffix, Getname.size() -indexSuffix, indexSuffix);
370  int Check_2 = GetnameSuffix.compare(theSuffix);
371  if ( Check_1 == 1 && (!Check_2) )
372  {
373  *theOutputIterator = StringType(theEntry->getName(), theMemoryManager);
374  }
375  }
376  }
377  }
378  theEntry = (FindFileStruct*)readdir(theDirectory);
379  } //while
380  }//try
381 
382  catch(...)
383  {
384  closedir(theDirectory);
385 
386  throw;
387  }
388  if( target_Dir )
389  chdir("..");
390  else
391  chdir("../..");
392  closedir(theDirectory);
393  }
394  }
395 
396 #endif
397 }
398 
399 
400 
401 template<class OutputIteratorType,
402  class FilterPredicateType,
403  class StringType,
404  class StringConversionFunction>
405 void
407  MemoryManager& theMemoryManager,
408  const StringType& theDirectory,
409  const StringType& theSearchSpec,
410  OutputIteratorType theOutputIterator,
411  FilterPredicateType theFilterPredicate,
412  StringConversionFunction theConversionFunction,
413 #if defined(XALAN_TEMPLATE_FUNCTION_NO_DEFAULT_PARAMETERS)
414  bool fIncludeSelfAndParent)
415 #else
416  bool fIncludeSelfAndParent = false)
417 #endif
418 {
419  StringType theFullSearchSpec(theDirectory, theMemoryManager);
420 
421  theFullSearchSpec += theSearchSpec;
422 
424  theMemoryManager,
425  theFullSearchSpec,
426  theOutputIterator,
427  theFilterPredicate,
428  theConversionFunction,
429  fIncludeSelfAndParent);
430 }
431 
432 
433 
434 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
435 template<class CollectionType, class StringType>
436 struct DirectoryEnumeratorFunctor
437 {
438  CollectionType
439  operator()(const StringType& theDirectory) const
440  {
441  CollectionType theCollection;
442 
443  operator()(theDirectory,
444  theCollection);
445 
446  return theCollection;
447  }
448 
449  void
450  operator()(
451  const StringType&,
452  const CollectionType&) const
453  {
454  }
455 };
456 #else
457 template<class CollectionType,
458  class StringType = XalanDOMString,
459  class FilterPredicateType = FilesOnlyFilterPredicate,
460  class StringConversionFunction = c_wstr_functor>
462 {
463  explicit
465  MemoryManager& theMemoryManager,
466  bool fIncludeSelfAndParent = false) :
467  m_includeSelfAndParent(fIncludeSelfAndParent),
468  m_memoryManager(theMemoryManager)
469  {
470  }
471 
472  void
474  const StringType& theFullSearchSpec,
475  CollectionType& theCollection) const
476  {
477  using std::back_inserter;
478 
480  m_memoryManager,
481  theFullSearchSpec,
482  std::back_inserter(theCollection),
483  m_filterPredicate,
484  m_conversionFunction,
485  m_includeSelfAndParent);
486  }
487 
488  CollectionType
489  operator()(const StringType& theFullSearchSpec) const
490  {
491  CollectionType theCollection;
492 
493  operator()(
494  theFullSearchSpec,
495  theCollection);
496 
497  return theCollection;
498  }
499 
500  void
502  const StringType& theDirectory,
503  const StringType& theSearchSpec,
504  CollectionType& theCollection) const
505  {
507  m_memoryManager,
508  theDirectory,
509  theSearchSpec,
510  std::back_inserter(theCollection),
511  m_filterPredicate,
512  m_conversionFunction,
513  m_includeSelfAndParent);
514  }
515 
516  CollectionType
518  const StringType& theDirectory,
519  const StringType& theSearchSpec) const
520  {
521  CollectionType theCollection;
522 
523  operator()(
524  theDirectory,
525  theSearchSpec,
526  theCollection);
527 
528  return theCollection;
529  }
530 
531 private:
532 
533  FilterPredicateType m_filterPredicate;
534 
535  StringConversionFunction m_conversionFunction;
536 
537  const bool m_includeSelfAndParent;
538 
539  MemoryManager& m_memoryManager;
540 };
541 #endif
542 
543 
544 
545 }
546 
547 
548 
549 #endif // DIRECTORY_ENUMERATOR_HEADER_GUARD_1357924680
xalanc::DirectoryEnumeratorFunctor::operator()
void operator()(const StringType &theDirectory, const StringType &theSearchSpec, CollectionType &theCollection) const
Definition: DirectoryEnumerator.hpp:501
XalanUnicode.hpp
XALAN_CPP_NAMESPACE
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
Definition: XalanVersion.hpp:76
xalanc::XalanVector::back
reference back()
Definition: XalanVector.hpp:637
xalanc::FindFileStruct
Definition: DirectoryEnumerator.hpp:133
xalanc::XalanVector::pop_back
void pop_back()
Definition: XalanVector.hpp:219
xalanc::XalanDOMString::substr
XalanDOMString & substr(XalanDOMString &theSubstring, size_type thePosition=0, size_type theCount=size_type(npos)) const
Definition: XalanDOMString.hpp:595
xalanc::XalanVector
Definition: XalanVector.hpp:58
XalanFileOutputStream.hpp
xalanc::DirectoryEnumeratorFunctor::operator()
CollectionType operator()(const StringType &theDirectory, const StringType &theSearchSpec) const
Definition: DirectoryEnumerator.hpp:517
xalanc::DirectoryEnumeratorFunctor::operator()
CollectionType operator()(const StringType &theFullSearchSpec) const
Definition: DirectoryEnumerator.hpp:489
xalanc::XalanDOMString::compare
int compare(const XalanDOMString &theString) const
Definition: XalanDOMString.hpp:612
xalanc::XalanDOMString::size
size_type size() const
Definition: XalanDOMString.hpp:201
xalanc::DirectoryFilterPredicate::operator()
bool operator()(const FindFileStruct &theFindData) const
Definition: DirectoryEnumerator.hpp:204
DOMStringHelper.hpp
PlatformSupportDefinitions.hpp
xalanc::DirectoryEnumeratorFunctor::DirectoryEnumeratorFunctor
DirectoryEnumeratorFunctor(MemoryManager &theMemoryManager, bool fIncludeSelfAndParent=false)
Definition: DirectoryEnumerator.hpp:464
xalanc::FindFileStruct::getName
const char * getName() const
Retrieve name of file.
Definition: DirectoryEnumerator.hpp:142
xalanc::TranscodeToLocalCodePage
TranscodeToLocalCodePage(const XalanDOMChar *theSourceString, XalanDOMString::size_type theSourceStringLength, CharVectorType &targetVector, bool terminate=false)
Convert a XalanDOMChar string to C++ standard library vector, transcoding to the default local code p...
xalanc::FilesOnlyFilterPredicate::operator()
bool operator()(const FindFileStruct &theFindData) const
Definition: DirectoryEnumerator.hpp:215
xalanc::c_str
const char * c_str(const CharVectorType &theString)
Get the underlying representation of the target CharVectorType as a null-terminated string.
Definition: DOMStringHelper.hpp:114
xalanc::XalanVector::size
size_type size() const
Definition: XalanVector.hpp:534
xalanc::FindFileStruct::isSelfOrParent
bool isSelfOrParent() const
Definition: DirectoryEnumerator.hpp:168
xalanc::FindFileStruct::isDirectory
bool isDirectory() const
Determine whether file is a directory.
Definition: DirectoryEnumerator.hpp:152
xalanc::XalanVector::push_back
void push_back(const value_type &data)
Definition: XalanVector.hpp:209
xalanc::DirectoryFilterPredicate
Definition: DirectoryEnumerator.hpp:201
xalanc::DirectoryEnumeratorFunctor
Definition: DirectoryEnumerator.hpp:461
xalanc::EnumerateDirectory
void EnumerateDirectory(MemoryManager &theMemoryManager, const StringType &theDirectory, const StringType &theSearchSpec, OutputIteratorType theOutputIterator, FilterPredicateType theFilterPredicate, StringConversionFunction theConversionFunction, bool fIncludeSelfAndParent=false)
Definition: DirectoryEnumerator.hpp:406
xalanc::XalanDOMString
Definition: XalanDOMString.hpp:45
xalanc::FilesOnlyFilterPredicate
Definition: DirectoryEnumerator.hpp:212
xalanc::DirectoryEnumeratorFunctor::operator()
void operator()(const StringType &theFullSearchSpec, CollectionType &theCollection) const
Definition: DirectoryEnumerator.hpp:473
xalanc::XalanVector< char >::size_type
size_t size_type
Definition: XalanVector.hpp:68