Path Iterator API

API Reference


Paths are text strings that contain nodes separated by character separators. Paths are used in many common applications like file system addressing, URLs, etc. so being able to parse them is quite important.

The Path Iterator API is intended for general purpose use and supports UTF-8 null-terminated strings and multi-character separators.

This API can be used to iterate over paths, traversing the path node-by-node. Or creating and combining paths together while ensuring that the resultant paths are properly normalized. For instance the following path:

 /a//path/to/a///some/../place

Would be normalized to the path:

 /a/path/to/a/place

Create a Path Iterator

Before iterating over a path, a path object must first be created by calling either le_pathIter_Create(), or le_pathIter_CreateForUnix(). le_pathIter_Create() will allow you to create an iterator for one of many different path styles. While le_pathIter_CreateForUnix() will create an iterator preconfigured for Unix style paths.

All strings to this API must be formatted as UTF-8 null-terminated strings.

When the path object is no longer needed, it can be deleted by calling le_pathIter_Delete().

Iterating a Path

Once an object is created, the nodes in it can be accessed using le_pathIter_GoToNext(), or le_pathIter_GoToPrev(). To start over at the beginning of the path call le_pathIter_GoToStart(). To position the iterator at the end of the path, use le_pathIter_GoToEnd(). On creation, the default position of the iterator is at the end of the path.

Code sample, iterate over an entire path:

// Create an iterator object, and move it to the front of the path.
 
if (le_pathIter_IsEmpty(iteratorRef))
{
return;
}
 
le_pathIter_GoToStart(iteratorRef);
 
// Now go through all of the path nodes and print out each one.
do
{
char buffer[BUFFER_SIZE] = { 0 };
 
if (le_pathIter_GetCurrentNode(iteratorRef, buffer, BUFFER_SIZE) == LE_OK)
{
printf("%s\n", buffer);
}
}
while (le_pathIter_GoToNext(iteratorRef) != LE_NOT_FOUND);
 
// All done with the iterator, so free it now.
le_pathIter_Delete(iteratorRef);
Note
le_pathIter_GetNextNode() and le_pathIter_GetPreviousNode() treat consecutive separators as a single separator.

Absolute versus Relative Paths

Absolute paths begin with one or more separators. Relative paths do not begin with a separator. le_pathIter_IsAbsolute() can be used to determine if the path is absolute or relative.

Modifying Paths

In addition to pure iteration, the path iterator can allow you to modify a path. For instance, you can iterate to a node in the path and use le_pathIter_Truncate() to truncate everything at and after that point. While you can use le_pathIter_Append() to add new path nodes at the end of the path.

Take the following code:

le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/path/to/a/place");
char fullPath[PATH_SIZE] = { 0 };
 
le_pathIter_GoToStart(iteratorRef);
 
le_pathIter_GoToNext(iteratorRef);
le_pathIter_GoToNext(iteratorRef);
le_pathIter_GoToNext(iteratorRef);
 
le_pathIter_Truncate(iteratorRef);
 
le_pathIter_Append(iteratorRef, "nowhere");
 
le_pathIter_GetPath(iteratorRef, fullPath, PATH_SIZE);
 
LE_ASSERT(strcmp(fullPath, "/a/path/to/nowhere") == 0);

Note that le_pathIter_Append() will also normalize paths as it appends. So, the following example has the same effect as the previous one.

le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/path/to/a/place");
char fullPath[PATH_SIZE] = { 0 };
 
le_pathIter_Append(iteratorRef, "../../nowhere");
le_pathIter_GetPath(iteratorRef, fullPath, PATH_SIZE);
 
le_pathIter_GetPath(iteratorRef, fullPath, PATH_SIZE);
 
LE_ASSERT(strcmp(fullPath, "/a/path/to/nowhere") == 0);