The Artima Developer Community
Sponsored Link

The C++ Source
Listing 3 - The readdir_sequence Class

Shows how to navigate UNIX-style directory entries with the readdir_sequence class. It is from the article Reading Unix-style Directories via STL-compliant Sequences.

// Listing 3: Implementation of readdir_sequence class

/* /////////////////////////////////////////////////////////////
 * Extract from unixstl_readdir_sequence.h
 *
 * www:        http://www.synesis.com.au/unixstl
 *             http://www.unixstl.org/
 *
 * Copyright (C) 2002-2004, Synesis Software Pty Ltd.
 * (Licensed under the Synesis Software Standard Source License:
 *  http://www.synesis.com.au/licenses/ssssl.html)
 * ////////////////////////////////////////////////////////// */

#include "unixstl.h"                    // UNIXSTL root header
#include "unixstl_filesystem_traits.h"  // filesystem_traits
#if defined(PATH_MAX)
# include "stlsoft_static_string.h"     // stlsoft::basic_static_string
#else /* ? PATH_MAX */
# include "stlsoft_simple_string.h"     // stlsoft::basic_simple_string
#endif /* !PATH_MAX */
#include "stlsoft_iterator.h"           // iterator base classes
#include <sys/types.h>
#include <sys/stat.h>                   // stat
#include <dirent.h>                     // opendir(), etc.
#include <unistd.h>                     // PATH_MAX (or not!)

class readdir_sequence
{
public:
  typedef readdir_sequence                    class_type;
private:
  typedef filesystem_traits<char>             traits_type;
public:
  typedef size_t                              size_type;
  class                                       const_iterator;
  typedef struct dirent const                 *value_type;

private:
#if defined(PATH_MAX)
  typedef stlsoft::basic_static_string< char
                                      , PATH_MAX
                                      >       string_type;
#else /* ? PATH_MAX */
  typedef stlsoft::basic_simple_string< char
                                      >       string_type;
#endif /* !PATH_MAX */

public:
  enum
  {
      includeDots = 0x0008  /*!< Dots directories included in returned sequence */
    , directories = 0x0010  /*!< Causes the search to include directories */
    , files       = 0x0020  /*!< Causes the search to include files */
  };

// Construction
public:
  readdir_sequence(char const *directory, unsigned flags = directories | files);

// Iteration
public:
  const_iterator  begin() const;
  const_iterator  end() const;

// Attributes
public:
  bool empty() const;

  string_type const &get_directory() const;

// Implementation
private:
  static unsigned validate_flags_(unsigned flags);

// Members
private:
  string_type m_directory;
  unsigned    m_flags;
};

/* /////////////////////////////////////////////////////////////////////////////
 * Implementation
 */

inline /* static */ unsigned readdir_sequence::validate_flags_(unsigned flags)
{
  return (0 == (flags & (directories | files)))
            ? (flags | (directories | files))
            : flags;
}

inline readdir_sequence::readdir_sequence(us_char_a_t const *directory
                                        , unsigned          flags)
  : m_directory(directory)
  , m_flags(validate_flags_(flags))
{
  if(!traits_type::has_dir_end(directory))
  {
    m_directory += traits_type::path_name_separator();
  }
}

inline readdir_sequence::const_iterator readdir_sequence::begin() const
{
  DIR *dir = opendir(m_directory.c_str());

  return const_iterator(dir, m_directory, m_flags);
}

inline readdir_sequence::const_iterator readdir_sequence::end() const
{
  return const_iterator();
}

inline us_bool_t readdir_sequence::empty() const
{
  return begin() != end();
}

inline readdir_sequence::string_type const &readdir_sequence::get_directory() const
{
  return m_directory;
}

Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us