
The Shore Project Group
Computer Sciences Department
UW-Madison
Madison, WI
The DirScan class provides a convenient interface for scanning directories. This document describes how to use the DirScan class. The Shore release includes a simple example program called shls (``Shore ls''), that illustrates the use of the DirScan class. Shls can be found in the examples/shls directory of the Shore release.
An application scans a directory by creating a DirScan object. DirScan objects are transient C++ objects, not persistent Shore objects. A DirScan object can be in one of two states: open or closed. A scan must be opened inside a transaction, and can only be used inside the transaction in which it was opened. Once a scan is opened, it stays open until it is explicitly closed, or until the scan object is destroyed, or the transaction terminates. This means, for example, that the scan object remains open even after the end of the scan has been reached, or if an error condition has been encountered.
Directory scans request blocks of directory entries from the Shore server and store them in a buffer. Applications can set the size of this buffer, although the size must be at least DEF_DIRSCAN_BUFSIZE to ensure that the buffer is large enough to hold at least one directory entry. If a smaller buffer size is requested, it will be rounded up to the default size.
A scan of a directory returns some number of DirEntry structures. The DirEntry type (defined in OCTypes.h) looks like this:
struct DirEntry
{
LOID loid;
int namelen;
char name[MAXNAMLEN + 1];
};
The fields of the structure are:
The public portion of the DirScan class is defined as follows:
class DirScan
{
public:
DirScan();
DirScan(const char *path, int bufsize = DEF_DIRSCAN_BUFSIZE);
shrc open(const char *path, int bufsize = DEF_DIRSCAN_BUFSIZE);
shrc next(DirEntry *entry);
~DirScan();
shrc close();
bool is_open();
shrc rc();
int operator==(shrc &rc);
int operator!=(shrc &rc);
};
Here, we describe each of the methods of DirScan:
These operators provide a convenient way to check the status of the scan. For example, applications can say: if(scan == RCOK) ... or if (scan != RCOK) ....
The following function prints the name and loid of each entry in the directory given by the pathname argument.
int count(const char *pathname)
{
DirEntry entry;
int count = 0;
// Open a scan over the pool given by "pathname."
DirScan scan(pathname);
// Make sure the scan was successfully opened.
if(scan != RCOK){
cout << "Error scanning directory " << pathname << ": "
<< rc << endl;
return 0;
}
// Scan until end-of-scan or an error is encountered.
for(count = 0; scan.next(&entry) == RCOK; ++count);
cout << path << " has " << count << " objects." << endl;
// Check for errors.
if(scan.rc().err_num() != OC_EndOfScan){
cout << "Error scanning directory " << pathname << ": "
<< rc << endl;
return 0;
}
// The destructor will close the scan object.
return count;
}