diff --git a/CMakeLists.txt b/CMakeLists.txt index 44db9e9..e06322e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -301,6 +301,7 @@ add_executable(alltests test/test_authenticators.cc test/test_string.cc test/test_slist.cc + test/test_path.cc ) target_link_libraries(alltests PUBLIC webfuse-adapter-static webfuse-provider-static webfuse-core ${EXTRA_LIBS} ${GMOCK_LIBRARIES} ${GTEST_LIBRARIES}) diff --git a/lib/webfuse/core/path.c b/lib/webfuse/core/path.c index 609b3c7..464e22d 100644 --- a/lib/webfuse/core/path.c +++ b/lib/webfuse/core/path.c @@ -1,17 +1,82 @@ #include "webfuse/core/path.h" +#include +#include + +#define WF_PATH_DEFAULT_CAPACITY (8) + +struct wf_path +{ + char * * elements; + size_t count; + size_t capacity; +}; + +static void +wf_path_add( + struct wf_path * path, + char const * element, + size_t element_size) +{ + if (0 < element_size) + { + if (path->count >= path->capacity) + { + size_t new_capacity = 2 * path->capacity; + size_t new_size = sizeof(char*) * new_capacity; + + char * * elements = realloc(path->elements, new_size); + if (NULL != elements) + { + path->elements = elements; + path->capacity = new_capacity; + } + } + + if (path->count < path->capacity) + { + path->elements[path->count] = strndup(element, element_size); + path->count++; + } + } +} struct wf_path * wf_path_create( char const * value) { - (void) value; - return NULL; + struct wf_path * path = malloc(sizeof(struct wf_path)); + if (NULL != path) + { + path->elements = malloc(sizeof(char*) * WF_PATH_DEFAULT_CAPACITY); + path->capacity = WF_PATH_DEFAULT_CAPACITY; + path->count = 0; + + char const * remainder = value; + char const * pos = strchr(remainder, '/'); + while (NULL != pos) + { + wf_path_add(path, remainder, (pos - remainder)); + remainder = pos + 1; + pos = strchr(remainder, '/'); + } + + wf_path_add(path, remainder, strlen(remainder)); + } + + return path; } void wf_path_dispose( struct wf_path * path) { + for(size_t i = 0; i < path->count; i++) + { + free(path->elements[i]); + } + + free(path->elements); + free(path); (void) path; } @@ -19,8 +84,7 @@ size_t wf_path_element_count( struct wf_path * path) { - (void) path; - return 0; + return path->count; } char const * @@ -28,7 +92,11 @@ wf_path_get_element( struct wf_path * path, size_t i) { - (void) path; - (void) i; - return NULL; + char const * result = NULL; + if (i < path->count) + { + result = path->elements[i]; + } + + return result; } diff --git a/test/test_path.cc b/test/test_path.cc new file mode 100644 index 0000000..93783ec --- /dev/null +++ b/test/test_path.cc @@ -0,0 +1,58 @@ +#include +#include "webfuse/core/path.h" + +TEST(wf_path, empty) +{ + struct wf_path * path = wf_path_create(""); + ASSERT_EQ(0, wf_path_element_count(path)); + ASSERT_EQ(nullptr, wf_path_get_element(path, 0)); + + wf_path_dispose(path); +} + +TEST(wf_path, relative_file) +{ + struct wf_path * path = wf_path_create("some.file"); + ASSERT_EQ(1, wf_path_element_count(path)); + ASSERT_STREQ("some.file", wf_path_get_element(path, 0)); + + wf_path_dispose(path); +} + +TEST(wf_path, absolute_file) +{ + struct wf_path * path = wf_path_create("/absolute.file"); + ASSERT_EQ(1, wf_path_element_count(path)); + ASSERT_STREQ("absolute.file", wf_path_get_element(path, 0)); + + wf_path_dispose(path); +} + +TEST(wf_path, nested_path) +{ + struct wf_path * path = wf_path_create("/a/nested/path"); + ASSERT_EQ(3, wf_path_element_count(path)); + ASSERT_STREQ("a", wf_path_get_element(path, 0)); + ASSERT_STREQ("nested", wf_path_get_element(path, 1)); + ASSERT_STREQ("path", wf_path_get_element(path, 2)); + + wf_path_dispose(path); +} + +TEST(wf_path, deep_nested_path) +{ + struct wf_path * path = wf_path_create("/this/is/a/very/deep/nested/path/to/some/file"); + ASSERT_EQ(10, wf_path_element_count(path)); + ASSERT_STREQ("this", wf_path_get_element(path, 0)); + ASSERT_STREQ("is", wf_path_get_element(path, 1)); + ASSERT_STREQ("a", wf_path_get_element(path, 2)); + ASSERT_STREQ("very", wf_path_get_element(path, 3)); + ASSERT_STREQ("deep", wf_path_get_element(path, 4)); + ASSERT_STREQ("nested", wf_path_get_element(path, 5)); + ASSERT_STREQ("path", wf_path_get_element(path, 6)); + ASSERT_STREQ("to", wf_path_get_element(path, 7)); + ASSERT_STREQ("some", wf_path_get_element(path, 8)); + ASSERT_STREQ("file", wf_path_get_element(path, 9)); + + wf_path_dispose(path); +} \ No newline at end of file