Sord Programming Manual

Peter Jones

    pjones@pmade.org

Copyright  2001, 2002 by Peter Jones

This manual describes the sord library and how it is used.

Redistribution and use in source (SGML DocBook) and 'compiled' forms (SGML,
HTML, PDF, PostScript, RTF and so forth) with or without modification, are
permitted provided that the following conditions are met:

 1. Redistributions of source code (SGML DocBook) must retain the above
    copyright notice, this list of conditions and the following disclaimer
    as the first lines of this file unmodified.
   
 2. Redistributions in compiled form (transformed to other DTDs, converted
    to PDF, PostScript, RTF and other formats) must reproduce the above
    copyright notice, this list of conditions and the following disclaimer
    in the documentation and/or other materials provided with the
    distribution.
   
    Important: THIS DOCUMENTATION IS PROVIDED BY THE AUTHORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD DOCUMENTATION
    PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
---------------------------------------------------------------------------

Table of Contents
1. Introduction
   
    1.1. What is sord?
   
2. The sord::entry Class
   
    2.1. Class Construction
    2.2. Class Usage
   
3. The sord::directory Class
   
    3.1. Class Construction
    3.2. Class Usage
    3.3. Directory Recursion
   
A. Requirements
   
    A.1. Dependencies
    A.2. Successful Builds
   
B. Building sord
   
    B.1. Building on Unix
    B.2. Building on Win32
   
C. To Do List
   
    C.1. Things TODO for version 0.4.0
    C.2. Things That Need to be Changed
    C.3. New Features to be Added
    C.4. Features That May Get Added
   
D. Revision History
   
    D.1. Version 0.3.0
    D.2. Version 0.2.0
    D.3. Version 0.1.0
   
E. Credits

List of Tables
A-1. Platform List

List of Examples
2-1. Constructing a sord::entry
3-1. Constructing a sord::directory
3-2. Iterating Through a Directory's Contents

---------------------------------------------------------------------------

Chapter 1. Introduction

1.1. What is sord?

sord is a C++ library that wraps around the operating system API for
reading directories. It is cross-platform and thread-safe.

With sord it is very easy to access information about files and list the
contents of directories. All without having to worry about using readdir,
readdir_r, or FindFileFirst.

Not only do you have freedom from the awkward system calls for getting
directory information, you also don't have to worry about file or directory
handles when you recurse into subdirectories. sord only gives you back
subdirectories after you have seen all the files in a directory and it has
closed the directory.

Finally, sord has a nice standard container-like API. You open a directory,
and then use an iterator to walk the list of entries in that directory.

---------------------------------------------------------------------------

Chapter 2. The sord::entry Class

The sord::entry class is used to get information about a file system entry.
This chapter describes the interface of the entry class.

---------------------------------------------------------------------------

2.1. Class Construction

The sord::entry constructor takes one parameter, a string that specifies
the path to the file system entry to get information about. This path can
be relative or absolute.

Example 2-1. Constructing a sord::entry

    #include <sord/entry.h>
    #include <iostream>
    
    int main (void) {
        sord::entry somefile("somefile.txt");
    
        if (!somefile) {
            std::cerr << "can't open somefile.txt\n";
            return 1;
        }
    
        return 0;
    }
           

Notice in the example how I used the class in the if statement with the
negation operator. This concept is borrowed from the std::iostream class.

With the sord::entry class, the overloaded ! operator will return true if
there was an error with the path given to the constructor. If the entry
does not exist in the file system this overloaded operator would return
true.

---------------------------------------------------------------------------

2.2. Class Usage

Once you have constructed a sord::entry it can be used to get information
about the file system entry that the object represents. There are a few
get_* member functions that you can use to get various information. See the
reference manual for more information.

---------------------------------------------------------------------------

Chapter 3. The sord::directory Class

The sord::directory class is used to read the contents of a directory. It
provides a const_iterator class that can be used to iterate through the
directory's contents.

---------------------------------------------------------------------------

3.1. Class Construction

The sord::directory constructor takes either a string parameter that
contains the path to a directory, or a sord::entry object that represents a
directory.

Example 3-1. Constructing a sord::directory

    #include <sord/directory.h>
    #include <iostream>
    
    int main (void) {
        sord::directory somedir("somedir");
    
        if (!somedir) {
            std::cerr << "can't open somedir\n";
            return 1;
        }
    
        return 0;
    }
           

You can see from the example that the sord::directory class overloads the
negation operator similar to the sord::entry class. This is how you can
check if the directory was opened successfully or not.

---------------------------------------------------------------------------

3.2. Class Usage

Once you have a constructed sord::directory class, you can get a
const_iterator to iterate over the directory's contents.

    Note: Because of the underlining operating system calls for reading
    directories, you cannot make a copy of a const_iterator or a sord::
    directory.
   
    When you create a const_iterator you must create a reference and the
    begin and end member functions will return a reference to a
    const_iterator.
   
Example 3-2. Iterating Through a Directory's Contents

    #include <sord/entry.h>
    #include <sord/directory.h>
    #include <iostream>
    
    int main (void) {
        sord::directory somedir(".");
    
        if (!somedir) {
            std::cerr << "can't open somedir\n";
            return 1;
        }
    
        sord::directory::const_iterator &i = somedir.begin();
        sord::directory::const_iterator &end = somedir.end();
    
        for (; i != end; ++i) {
            // do something with the directory entry
            std::cout << i->get_name() << "\n";
        }
    
        return 0;
    }
           
---------------------------------------------------------------------------

3.3. Directory Recursion

Many operating systems present problems to the programmer who wants to
recurse down a directory tree. You may risk using too much memory or file
descriptors under these systems.

sord does a couple of neat things to allow you to recurse down a directory
tree. First, the sord::directory's const_iterator will return all
non-directory entries first. It keeps all directories stored in memory and
when the last directory entry is reached it closes the directory.

After closing the directory (which solves the memory and file descriptor
problems), the const_iterator will start returning the directories. You can
then use the const_iterator to construct a sord::directory and recurse down
the tree.

    Note: Unlike the operating system directory reading functions, the
    sord::directory class does not return the current directory "." or the
    parent directory "..".
   
---------------------------------------------------------------------------

Appendix A. Requirements

A.1. Dependencies

Although sord does not have any external dependencies at runtime, it does
require you to have perl installed for bootstrapping. The current
configuration system needs perl in order to figure out compiler flags and
to generate Makefiles.

---------------------------------------------------------------------------

A.2. Successful Builds

sord is known to compile and work on the following systems. It should
compile on all modern versions of Unix using the GCC compiler.

If your system is not listed here, and you were able to compile and use
sord, please drop us a note.

Table A-1. Platform List

+-----------------------------------------------------------------+
|Platform|Operating System|Compiler                       |Notes  |
|--------+----------------+-------------------------------+-------|
|ix86    |FreeBSD 4.X     |GCC versions 2.95.X and GCC 3.X|N/A    |
|--------+----------------+-------------------------------+-------|
|Sparc   |Solaris 2.7     |GCC 3.X                        |1      |
|--------+----------------+-------------------------------+-------|
|Sparc   |Solaris 2.7     |Sun Forte C++ 6.2              |1      |
|--------+----------------+-------------------------------+-------|
|PowerPC |Mac OS X        |Apple GCC                      |2      |
|--------+----------------+-------------------------------+-------|
|ix86    |Cygwin          |GCC 2.95.2                     |2 and 4|
|--------+----------------+-------------------------------+-------|
|ix86    |Win32           |MSVC 6.0                       |3      |
+-----------------------------------------------------------------+

Platform Notes

 1. The directory recursive test is very slow on this platform.
   
 2. There does not seem to be support for readdir_r on this platform.
   
 3. You must have the STLport installed and correctly setup to build sord.
   
 4. The recursive directory test fails due to a limit on the length of a
    directory path.
   
---------------------------------------------------------------------------

Appendix B. Building sord

B.1. Building on Unix

This section describes the steps for building sord on Unix-like platforms.
This includes cygwin on Win32.

The first thing that you need to do is run the configure.pl perl script.
This script will try to figure out if your system supports readdir_r or
not.

    Note: Before you run configure.pl you should set your CXX environment
    variable. This variable should be set to the path to the C++ compiler
    that you want to use. If this variable is not set, configure.pl will
    default to c++.
   
You can give some flags to configure.pl to change its behavior. Use the
--help command line option to see a list of supported flags.

After you run configure.pl you should have a set of Makefiles that can be
used to compile sord. Running make should be enough.

---------------------------------------------------------------------------

B.2. Building on Win32

This section covers the building of sord under the Microsoft Visual Studio
6.0 compiler.

Before you can build sord, you need to have the STLport installed. sord
will not compile without this due to bugs in the C++ standard library that
came with MSVC 6.0. Your other option is to upgrade the standard library.

Building sord under Win32 is stright forward. Use the MSVC workspace file
that is in the platform/Win32 directory included with sord.

---------------------------------------------------------------------------

Appendix C. To Do List

For your entertainment, I now present to you a list of things that need to
be done to sord.

---------------------------------------------------------------------------

C.1. Things TODO for version 0.4.0

  * Add is_readable, is_writeable, is_executable functions for sord::entry.
   
  * Add get_uid and get_gid functions for sord::entry.
   
  * Add rename and unlink functions for sord::entry.
   
  * Write tests for new functions.
   
---------------------------------------------------------------------------

C.2. Things That Need to be Changed

  * Add non-const iterators for sord::directory.
   
---------------------------------------------------------------------------

C.3. New Features to be Added

  * Add support for getting and setting the current working directory.
   
  * Add support for getting the UID and GID on a sord::entry.
   
  * Add support for setting entry attributes such as mode and timestamps.
   
---------------------------------------------------------------------------

C.4. Features That May Get Added

  * Add the ability to create directory paths.
   
  * Allow the removal of an entry from the file system.
   
---------------------------------------------------------------------------

Appendix D. Revision History

D.1. Version 0.3.0

  * Fixed a bug where multiple calls to sord::directory::begin() would
    cause duplicate directories to appear. (Win32 code only)
   
  * Fixed a bug where multiple calls to sord::directory::begin() could
    cause a std::vector::iterator to point to an invalid location. (Win32
    code only)
   
  * Add support for Darwin / MacOSX.
   
  * Added some bit masks in the form of an enum to better support the mode
    of an entry.
   
---------------------------------------------------------------------------

D.2. Version 0.2.0

Initial public release.

---------------------------------------------------------------------------

D.3. Version 0.1.0

Never released.

---------------------------------------------------------------------------

Appendix E. Credits

sord it brought to you by the following people.

  * Peter Jones
   
      + Designer, main developer and project maintainer
       
  * Isaac Foraker
   
      + Contributed optimized Win32 code to version 0.3.0
       
      + Original Win32 code that appeared in version 0.1
       
  * Chris Thatcher and Brian Little
   
      + Fixed a bug in the Win32 directory code for version 0.3.0
       
---------------------------------------------------------------------------
