Example #1
0
//--------------------------------------------------------------------------------------------------
tdb_NodeRef_t ni_GetNode
(
    ni_IteratorRef_t iteratorRef,  ///< The iterator object to access.
    const char* subPathPtr         ///< Optional, can be used to specify a node relative to the
                                   ///<   current one.
)
//--------------------------------------------------------------------------------------------------
{
    // Check to see if we have a current node.  If we do, then attempt to traverse from our current
    // node, to the requested sub-node.  If the new path is NULL or empty, then we'll just end up
    // getting our current node.
    if (iteratorRef->currentNodeRef != NULL)
    {
        le_pathIter_Ref_t newPathRef = le_pathIter_CreateForUnix(subPathPtr);
        tdb_NodeRef_t nodeRef = tdb_GetNode(iteratorRef->currentNodeRef, newPathRef);

        le_pathIter_Delete(newPathRef);

        return nodeRef;
    }

    // Ok, the iterator doesn't have a current node.  So, copy iterator's existing path, and append
    // the new sub path to the existing path.  Once that's done, attempt to find the requested node
    // in the tree.  If the node still can not be found, return NULL.
    le_pathIter_Ref_t newPathRef = le_pathIter_Clone(iteratorRef->pathIterRef);
    tdb_NodeRef_t nodeRef = NULL;
    le_result_t result = LE_OK;

    if (subPathPtr != NULL)
    {
        result = le_pathIter_Append(newPathRef, subPathPtr);
    }

    // Make sure that the append was successful.  If it is, get the node.
    if (result == LE_OVERFLOW)
    {
        tu_TerminateClient(iteratorRef->sessionRef, "Specified path too large.");
    }
    else if (result == LE_UNDERFLOW)
    {
        tu_TerminateClient(iteratorRef->sessionRef,
                           "Specified path attempts to iterate below root.");
    }
    else
    {
        nodeRef = tdb_GetNode(tdb_GetRootNode(iteratorRef->treeRef), newPathRef);
    }

    le_pathIter_Delete(newPathRef);

    return nodeRef;
}
Example #2
0
//--------------------------------------------------------------------------------------------------
tdb_NodeRef_t ni_TryCreateNode
(
    ni_IteratorRef_t iteratorRef,  ///< [IN] The iterator object to access.
    const char* subPathPtr         ///< [IN] Optional, can be used to specify a node relative to the
                                   ///<      current one.
)
//--------------------------------------------------------------------------------------------------
{
    // Clone the iterator's original path and, if supplied, append the new sub path onto this new
    // path.
    le_pathIter_Ref_t newPathRef = NULL;

    if (CloneAndAppendPath(iteratorRef, subPathPtr, &newPathRef) != LE_OK)
    {
        return NULL;
    }

    // Attempt to find the node in the tree.  If not found attempt to create the new node in the
    // tree.
    tdb_NodeRef_t rootNodeRef = tdb_GetRootNode(iteratorRef->treeRef);
    tdb_NodeRef_t nodeRef = tdb_GetNode(rootNodeRef, newPathRef);

    if (nodeRef == NULL)
    {
        nodeRef = tdb_CreateNodePath(rootNodeRef, newPathRef);
    }

    le_pathIter_Delete(newPathRef);
    return nodeRef;
}
Example #3
0
//--------------------------------------------------------------------------------------------------
void ni_Release
(
    ni_IteratorRef_t iteratorRef  ///< [IN] Free the resources used by this iterator.
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(iteratorRef != NULL);

    // Make sure that the transaction timer isn't still running.
    if (iteratorRef->timerRef != NULL)
    {
        if (le_timer_GetExpiryCount(iteratorRef->timerRef) == 0)
        {
            le_timer_Stop(iteratorRef->timerRef);
        }

        le_timer_Delete(iteratorRef->timerRef);
        iteratorRef->timerRef = NULL;
    }

    // Release the rest of the iterator's resources.
    LE_DEBUG("Releasing iterator, <%p> with a lifetime of %d seconds.",
             iteratorRef,
             (uint32_t)(le_clk_GetRelativeTime().sec - iteratorRef->creationTime.sec));

    ni_Close(iteratorRef);
    tdb_UnregisterIterator(iteratorRef->treeRef, iteratorRef);

    le_pathIter_Delete(iteratorRef->pathIterRef);

    tdb_ReleaseTree(iteratorRef->treeRef);
    le_mem_Release(iteratorRef);
}
Example #4
0
//--------------------------------------------------------------------------------------------------
le_result_t ni_GetNodeName
(
    ni_IteratorRef_t iteratorRef,  ///< [IN]  The iterator object to access.
    const char* pathPtr,           ///< [IN]  Optional path to another node in the tree.
    char* destBufferPtr,           ///< [OUT] The buffer to copy string data into.
    size_t bufferMax               ///< [IN]  The maximum size of the string buffer.
)
//--------------------------------------------------------------------------------------------------
{
    // Make sure we were given a buffer.
    if (bufferMax == 0)
    {
        return LE_OVERFLOW;
    }

    // If we have a current node, get it's name.  Otherwise we'll have to get the name from the
    // path.
    tdb_NodeRef_t nodeRef = ni_GetNode(iteratorRef, pathPtr);

    // If the iterator was closed during the GetNode, then that means there was a fatal problem
    // encountered.
    if (iteratorRef->isTerminated)
    {
        // At this point we know the client has been disconnected.  So just return fault so that the
        // calling code can know this.
        return LE_FAULT;
    }

    if (nodeRef != NULL)
    {
        return tdb_GetNodeName(nodeRef, destBufferPtr, bufferMax);
    }

    // Looks like a node wasn't found.  So, try to get the name of the node from the sub-path.  Or
    // if a sub-path was not specified, get the name from the iterator's base path.
    *destBufferPtr = '\0';

    if (strcmp(pathPtr, "") != 0)
    {
        le_pathIter_Ref_t subPathIter = le_pathIter_CreateForUnix(pathPtr);
        le_result_t result = le_pathIter_GoToEnd(iteratorRef->pathIterRef);

        if (result == LE_OK)
        {
            result = le_pathIter_GetCurrentNode(subPathIter, destBufferPtr, bufferMax);
        }

        le_pathIter_Delete(subPathIter);
        return result;
    }

    LE_ASSERT(le_pathIter_GoToEnd(iteratorRef->pathIterRef) == LE_OK);
    return le_pathIter_GetCurrentNode(iteratorRef->pathIterRef, destBufferPtr, bufferMax);
}
Example #5
0
//--------------------------------------------------------------------------------------------------
static le_result_t CloneAndAppendPath
(
    ni_IteratorRef_t iteratorRef,         ///< [IN]  The iterator to read.
    const char* subPathPtr,               ///< [IN]  Optionally, a sub-path to traverse to.
    le_pathIter_Ref_t* newPathIterRefPtr  ///< [OUT] Pointer to a to-be newly created ref.  Must be
                                          ///<       NULL on entry!
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(*newPathIterRefPtr == NULL);


    le_pathIter_Ref_t newPathRef = le_pathIter_Clone(iteratorRef->pathIterRef);
    le_result_t result = LE_OK;

    if (subPathPtr != NULL)
    {
        result = le_pathIter_Append(newPathRef, subPathPtr);
    }

    if (result != LE_OK)
    {
        char* terminateMessage;

        switch (result)
        {
            case LE_OVERFLOW:
                terminateMessage = "Specified path too large.";
                break;

            case LE_UNDERFLOW:
                terminateMessage = "Specified path attempts to iterate below root.";
                break;

            default:
                terminateMessage = "Unexpected error while appending path.";
                break;
        }

        iteratorRef->isTerminated = true;
        tu_TerminateConfigClient(iteratorRef->sessionRef, terminateMessage);

        le_pathIter_Delete(newPathRef);
        return result;
    }

    *newPathIterRefPtr = newPathRef;
    return result;
}
Example #6
0
//--------------------------------------------------------------------------------------------------
void ni_Release
(
    ni_IteratorRef_t iteratorRef  ///< Free the resources used by this iterator.
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(iteratorRef != NULL);

    LE_DEBUG("Releasing iterator, <%p>.", iteratorRef);

    ni_Close(iteratorRef);
    tdb_UnregisterIterator(iteratorRef->treeRef, iteratorRef);

    le_pathIter_Delete(iteratorRef->pathIterRef);

    tdb_ReleaseTree(iteratorRef->treeRef);
    le_mem_Release(iteratorRef);
}
Example #7
0
//--------------------------------------------------------------------------------------------------
le_result_t ni_GetPathForNode
(
    ni_IteratorRef_t iteratorRef,  ///< The iterator object to access.
    const char* subPathPtr,        ///< Optional, can be used to specify a node relative to the
                                   ///<   current one.
    char* destBufferPtr,           ///< The buffer to copy string data into.
    size_t bufferMax               ///< The maximum size of the string buffer.
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(iteratorRef != NULL);
    LE_ASSERT(destBufferPtr != NULL);
    LE_ASSERT(bufferMax > 0);

    // Check to see if they're looking for a path to a node relative to the current one.
    if (   (subPathPtr != NULL)
        && (strcmp(subPathPtr, "") != 0))
    {
        // Build up a new path based on the existing path.
        le_pathIter_Ref_t newPathRef = le_pathIter_Clone(iteratorRef->pathIterRef);
        le_result_t result = le_pathIter_Append(newPathRef, subPathPtr);

        if (result == LE_OVERFLOW)
        {
            tu_TerminateClient(iteratorRef->sessionRef, "Specified path too large.");
        }
        else if (result == LE_UNDERFLOW)
        {
            tu_TerminateClient(iteratorRef->sessionRef,
                               "Specified path attempts to iterate below root.");
        }
        else
        {
            result = le_pathIter_GetPath(newPathRef, destBufferPtr, bufferMax);
        }

        le_pathIter_Delete(newPathRef);
        return result;
    }

    // Simply return the current path.
    return le_pathIter_GetPath(iteratorRef->pathIterRef, destBufferPtr, bufferMax);
}
Example #8
0
//--------------------------------------------------------------------------------------------------
tdb_NodeRef_t ni_GetNode
(
    ni_IteratorRef_t iteratorRef,  ///< [IN] The iterator object to access.
    const char* subPathPtr         ///< [IN] Optional, can be used to specify a node relative to the
                                   ///<      current one.
)
//--------------------------------------------------------------------------------------------------
{
    // Copy iterator's existing path, and append the new sub path to the copied path.  Once
    // that's done, attempt to find the requested node in the tree.  If the node still can not be
    // found, return NULL.
    le_pathIter_Ref_t newPathRef = NULL;

    if (CloneAndAppendPath(iteratorRef, subPathPtr, &newPathRef) != LE_OK)
    {
        return NULL;
    }

    tdb_NodeRef_t nodeRef = tdb_GetNode(tdb_GetRootNode(iteratorRef->treeRef), newPathRef);

    le_pathIter_Delete(newPathRef);

    return nodeRef;
}
Example #9
0
static void TestUnixStyleAppends(void)
{
    LE_INFO("======== Test Unix Style Appends.");

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "x/y/z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/a/b/c/x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "../x/y/z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/a/b/x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "../../x/y/z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/a/x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "../../../x/y/z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "../../../../x/y/z") == LE_UNDERFLOW);
        LE_TEST(TestPath(iteratorRef, "/"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "../../../x/y/z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "../../../../x/y/z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "../x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "/x/y/z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "/x/y/z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("a/b/c");
        LE_TEST(le_pathIter_Append(iteratorRef, "./x/y/z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "a/b/c/x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("");
        LE_TEST(le_pathIter_Append(iteratorRef, "./x/y/./z") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "./x/y/z"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("");
        LE_TEST(le_pathIter_Append(iteratorRef, "/a//path/to/a///some/../place") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/a/path/to/a/place"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_Create("", "::", "^^", "__");
        LE_TEST(le_pathIter_Append(iteratorRef, "__::a::::path::to::__::a::some::^^::place") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "__::a::path::to::a::place"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_Create("::", "::", "^^", "__");
        LE_TEST(le_pathIter_Append(iteratorRef, "__::a::::path::to::__::a::some::^^::place") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "::a::path::to::a::place"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_Create("", "/", NULL, NULL);
        LE_TEST(le_pathIter_Append(iteratorRef, "/a//path/./to/a///some/../place") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/a/path/./to/a/some/../place"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("");
        LE_TEST(le_pathIter_Append(iteratorRef, "../../../a//path/") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "../../../a/path"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("");
        LE_TEST(le_pathIter_Append(iteratorRef, "/a//path/to/a///some/../place") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/a/path/to/a/place"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);

        LE_TEST(le_pathIter_GoToStart(iteratorRef) == LE_OK);

        LE_TEST(le_pathIter_GoToNext(iteratorRef) == LE_OK);
        LE_TEST(le_pathIter_GoToNext(iteratorRef) == LE_OK);
        LE_TEST(le_pathIter_GoToNext(iteratorRef) == LE_OK);

        le_pathIter_Truncate(iteratorRef);

        LE_TEST(le_pathIter_Append(iteratorRef, "nowhere") == LE_OK);

        LE_TEST(TestPath(iteratorRef, "/a/path/to/nowhere"));

        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("");
        LE_TEST(le_pathIter_Append(iteratorRef, "/a//path/to/a///some/../place") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/a/path/to/a/place"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);

        LE_TEST(le_pathIter_Append(iteratorRef, "../../nowhere") == LE_OK);

        LE_TEST(TestPath(iteratorRef, "/a/path/to/nowhere"));

        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/b/c");
        LE_TEST(TestPath(iteratorRef, "/a/b/c"));
        LE_TEST(le_pathIter_Append(iteratorRef, "..") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/a/b"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/b/c/");
        LE_TEST(TestPath(iteratorRef, "/a/b/c"));
        LE_TEST(le_pathIter_Append(iteratorRef, "..") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/a/b"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("a/b/c");
        LE_TEST(TestPath(iteratorRef, "a/b/c"));
        LE_TEST(le_pathIter_Append(iteratorRef, "..") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "a/b"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("a/b/c/");
        LE_TEST(TestPath(iteratorRef, "a/b/c"));
        LE_TEST(le_pathIter_Append(iteratorRef, "..") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "a/b"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a");
        LE_TEST(TestPath(iteratorRef, "/a"));
        LE_TEST(le_pathIter_Append(iteratorRef, "..") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/a/");
        LE_TEST(TestPath(iteratorRef, "/a"));
        LE_TEST(le_pathIter_Append(iteratorRef, "..") == LE_OK);
        LE_TEST(TestPath(iteratorRef, "/"));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == true);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("a");
        LE_TEST(TestPath(iteratorRef, "a"));
        LE_TEST(le_pathIter_Append(iteratorRef, "..") == LE_OK);
        LE_TEST(TestPath(iteratorRef, ""));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }

    {
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("a/");
        LE_TEST(TestPath(iteratorRef, "a"));
        LE_TEST(le_pathIter_Append(iteratorRef, "..") == LE_OK);
        LE_TEST(TestPath(iteratorRef, ""));
        LE_TEST(le_pathIter_IsAbsolute(iteratorRef) == false);
        le_pathIter_Delete(iteratorRef);
    }
}
Example #10
0
static void TestUnixStyleIterator(void)
{
    LE_INFO("======== Test Unix Style Iterator.");

    static const char* nodes[] = { "a", "path", "to", "some", "end" };
    static const char* nodes2[] = { "a", "b", "c", "d", "e" };

    {
        static const char path[] = "/a/path/to/some/end";

        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix(path);
        IteratePath(iteratorRef, path, nodes);
        le_pathIter_Delete(iteratorRef);
    }

    {
        static const char path[] = "::a::path::to::some::end";

        le_pathIter_Ref_t iteratorRef = le_pathIter_Create(path, "::", "..", ".");
        IteratePath(iteratorRef, path, nodes);
        le_pathIter_Delete(iteratorRef);
    }

    {
        static const char path[] = "/a/b/c/d/e";

        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix(path);
        IteratePath(iteratorRef, path, nodes2);
        le_pathIter_Delete(iteratorRef);
    }

    {
        static const char path[] = "::a::b::c::d::e";

        le_pathIter_Ref_t iteratorRef = le_pathIter_Create(path, "::", "..", ".");
        IteratePath(iteratorRef, path, nodes2);
        le_pathIter_Delete(iteratorRef);
    }

    {
        char buffer[LARGE_BUFFER_SIZE] = { 0 };
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("");

        LE_TEST(le_pathIter_GetCurrentNode(iteratorRef,
                                            buffer,
                                            LARGE_BUFFER_SIZE) == LE_NOT_FOUND);
        LE_TEST(strcmp(buffer, "") == 0);
    }

    {
        char buffer[LARGE_BUFFER_SIZE] = { 0 };
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/");

        le_pathIter_GoToStart(iteratorRef);
        LE_TEST(le_pathIter_GetCurrentNode(iteratorRef,
                                            buffer,
                                            LARGE_BUFFER_SIZE) == LE_NOT_FOUND);
        LE_TEST(strcmp(buffer, "") == 0);

        le_pathIter_GoToEnd(iteratorRef);
        LE_TEST(le_pathIter_GetCurrentNode(iteratorRef,
                                            buffer,
                                            LARGE_BUFFER_SIZE) == LE_NOT_FOUND);
        LE_TEST(strcmp(buffer, "") == 0);
    }

    {
        char buffer[LARGE_BUFFER_SIZE] = { 0 };
        le_pathIter_Ref_t iteratorRef = le_pathIter_CreateForUnix("/some/path/somewhere");

        le_pathIter_GoToStart(iteratorRef);
        LE_TEST(le_pathIter_GetCurrentNode(iteratorRef,
                                            buffer,
                                            LARGE_BUFFER_SIZE) == LE_OK);
        LE_TEST(strcmp(buffer, "some") == 0);

        le_pathIter_GoToEnd(iteratorRef);
        LE_TEST(le_pathIter_GetCurrentNode(iteratorRef,
                                            buffer,
                                            LARGE_BUFFER_SIZE) != LE_NOT_FOUND);
        LE_TEST(strcmp(buffer, "somewhere") == 0);
    }
}
Example #11
0
//--------------------------------------------------------------------------------------------------
le_result_t ni_SetNodeName
(
    ni_IteratorRef_t iteratorRef,  ///< [IN] The iterator object to access.
    const char* pathPtr,           ///< [IN] Optional path to another node in the tree.
    const char* namePtr            ///< [IN] The new name to use.
)
//--------------------------------------------------------------------------------------------------
{
    // Try to get or create the requested node.  If the optional sub-path results in a new path that
    // overflows, then the node get will fail.
    tdb_NodeRef_t nodeRef = ni_TryCreateNode(iteratorRef, pathPtr);
    le_result_t result = LE_OK;

    if (nodeRef)
    {
        // Ok, the existing path is ok.  Cache the existing node name, in case we have to revert it
        // later, then set the new name.  We may have to revert the name later, because, while the
        // new name itself may be ok.  The name may actually be too long for the path limit.
        char oldName[LE_CFG_NAME_LEN_BYTES] = "";
        LE_ASSERT(tdb_GetNodeName(nodeRef, oldName, sizeof(oldName)) == LE_OK);

        result = tdb_SetNodeName(nodeRef, namePtr);

        if (result == LE_OK)
        {
            // The new name passed validation, now we have to make sure that the full path to the
            // node is still ok.  So, first we have to check, was a relative path used.
            if (strcmp(pathPtr, "") == 0)
            {
                // Looks like the caller was using the iterator's current node.  So, remove the old
                // name from the end of the iterator's current path, and append the new name.  If
                // this fails, it's because the new absolute path is too long, so name change fails,
                // and we have to revert the changes.
                LE_ASSERT(le_pathIter_Append(iteratorRef->pathIterRef, "..") == LE_OK);
                result = le_pathIter_Append(iteratorRef->pathIterRef, namePtr);

                if (result != LE_OK)
                {
                    LE_ASSERT(le_pathIter_Append(iteratorRef->pathIterRef, oldName) == LE_OK);
                }
            }
            else
            {
                // The user is accessing a node relative to the iterator's current node.  So, we
                // need too build up a new path and validate that the new name still fits within our
                // limits.  The new path ref is for validation only and can be safely discarded once
                // the check is complete.
                le_pathIter_Ref_t newPathRef = le_pathIter_Clone(iteratorRef->pathIterRef);
                result = le_pathIter_Append(newPathRef, pathPtr);

                if (result == LE_OK)
                {
                    LE_ASSERT(le_pathIter_Append(newPathRef, "..") == LE_OK);
                    result = le_pathIter_Append(newPathRef, namePtr);
                }

                le_pathIter_Delete(newPathRef);
            }

            // If we got to this point and everything is ok, then we know that the name set was ok,
            // and that the resultant path with the new name is also ok.  So, make sure that this
            // node exists in the next commit.  Otherwise, revert the node to it's old name and
            // report the error to the caller.
            if (result == LE_OK)
            {
                tdb_EnsureExists(nodeRef);
            }
            else
            {
                LE_ASSERT(tdb_SetNodeName(nodeRef, oldName) == LE_OK);
            }
        }
    }

    return result;
}