Port the current code to new IncFS

Bug: 146080380
Test: manual, "cmd incremental install-start"

Change-Id: I6761c3f0e58b6d4de1ae3c4b31c23204fba9f740
diff --git a/services/incremental/path.cpp b/services/incremental/path.cpp
index c529d61..0d86f2a 100644
--- a/services/incremental/path.cpp
+++ b/services/incremental/path.cpp
@@ -44,16 +44,45 @@
                                         PathCharsLess());
 }
 
+static void preparePathComponent(std::string_view path, bool trimFront) {
+    if (trimFront) {
+        while (!path.empty() && path.front() == '/') {
+            path.remove_prefix(1);
+        }
+    }
+    while (!path.empty() && path.back() == '/') {
+        path.remove_suffix(1);
+    }
+}
+
 void details::append_next_path(std::string& target, std::string_view path) {
+    preparePathComponent(path, true);
     if (path.empty()) {
         return;
     }
-    if (!target.empty()) {
+    if (!target.empty() && !target.ends_with('/')) {
         target.push_back('/');
     }
     target += path;
 }
 
+std::string_view relativize(std::string_view parent, std::string_view nested) {
+    if (!nested.starts_with(parent)) {
+        return nested;
+    }
+    if (nested.size() == parent.size()) {
+        return {};
+    }
+    if (nested[parent.size()] != '/') {
+        return nested;
+    }
+    auto relative = nested.substr(parent.size());
+    while (relative.front() == '/') {
+        relative.remove_prefix(1);
+    }
+    return relative;
+}
+
 bool isAbsolute(std::string_view path) {
     return !path.empty() && path[0] == '/';
 }