فهرست منبع

Add a simple FileSystemPath class that can canonicalize paths.

Also a simple StringBuilder to help him out.
Andreas Kling 6 سال پیش
والد
کامیت
88ad59bfb1
6فایلهای تغییر یافته به همراه102 افزوده شده و 6 حذف شده
  1. 44 0
      AK/FileSystemPath.cpp
  2. 24 0
      AK/FileSystemPath.h
  3. 2 2
      AK/Makefile
  4. 1 0
      AK/String.h
  5. 17 3
      AK/StringBuilder.cpp
  6. 14 1
      AK/test.cpp

+ 44 - 0
AK/FileSystemPath.cpp

@@ -0,0 +1,44 @@
+#include "FileSystemPath.h"
+#include "Vector.h"
+#include "kstdio.h"
+#include "StringBuilder.h"
+
+namespace AK {
+
+FileSystemPath::FileSystemPath(const String& s)
+    : m_string(s)
+{
+    m_isValid = canonicalize();
+}
+
+bool FileSystemPath::canonicalize(bool resolveSymbolicLinks)
+{
+    // FIXME: Implement "resolveSymbolicLinks"
+    auto parts = m_string.split('/');
+    Vector<String> canonicalParts;
+
+    for (auto& part : parts) {
+        if (part == ".")
+            continue;
+        if (part == "..") {
+            if (!canonicalParts.isEmpty())
+                canonicalParts.takeLast();
+            continue;
+        }
+        canonicalParts.append(part);
+    }
+    if (canonicalParts.isEmpty()) {
+        m_string = "/";
+        return true;
+    }
+    StringBuilder builder;
+    for (auto& cpart : canonicalParts) {
+        builder.append('/');
+        builder.append(move(cpart));
+    }
+    m_string = builder.build();
+    return true;
+}
+
+}
+

+ 24 - 0
AK/FileSystemPath.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include "String.h"
+
+namespace AK {
+
+class FileSystemPath {
+public:
+    FileSystemPath() { }
+    explicit FileSystemPath(const String&);
+
+    bool isValid() const { return m_isValid; }
+    String string() const { return m_string; }
+
+private:
+    bool canonicalize(bool resolveSymbolicLinks = false);
+
+    String m_string;
+    bool m_isValid { false };
+};
+
+};
+
+using AK::FileSystemPath;

+ 2 - 2
AK/Makefile

@@ -1,11 +1,11 @@
 PROGRAM = akit-test
-OBJS = StringImpl.o String.o MappedFile.o TemporaryFile.o SimpleMalloc.o kmalloc.o test.o
+OBJS = StringImpl.o String.o MappedFile.o TemporaryFile.o SimpleMalloc.o kmalloc.o FileSystemPath.o StringBuilder.o test.o
 
 CXXFLAGS = -std=c++17 -O0 -W -Wall -ggdb3
 
 all:	$(PROGRAM)
 
-test.o: Vector.h String.h StringImpl.h MappedFile.h HashTable.h SinglyLinkedList.h Traits.h HashMap.h TemporaryFile.h Buffer.h
+test.o: Vector.h String.h StringImpl.h MappedFile.h HashTable.h SinglyLinkedList.h Traits.h HashMap.h TemporaryFile.h Buffer.h FileSystemPath.h StringBuilder.h
 
 .cpp.o:
 	$(CXX) $(CXXFLAGS) -o $@ -c $<

+ 1 - 0
AK/String.h

@@ -61,6 +61,7 @@ public:
     Vector<String> split(char separator) const;
     String substring(size_t start, size_t length) const;
 
+    bool isNull() const { return !m_impl; }
     bool isEmpty() const { return length() == 0; }
     unsigned length() const { return m_impl ? m_impl->length() : 0; }
     const char* characters() const { return m_impl ? m_impl->characters() : nullptr; }

+ 17 - 3
AK/StringBuilder.cpp

@@ -4,7 +4,7 @@ namespace AK {
 
 void StringBuilder::append(String&& str)
 {
-    m_strings.append(std::move(str));
+    m_strings.append(move(str));
 }
 
 void StringBuilder::append(char ch)
@@ -14,11 +14,25 @@ void StringBuilder::append(char ch)
 
 String StringBuilder::build()
 {
-    auto strings = std::move(m_strings);
+    auto strings = move(m_strings);
     if (strings.isEmpty())
         return String::empty();
 
-    return String();
+    size_t sizeNeeded = 1;
+    for (auto& string : strings)
+        sizeNeeded += string.length();
+
+    char* buffer;
+    auto impl = StringImpl::createUninitialized(sizeNeeded, buffer);
+    if (!impl)
+        return String();
+
+    for (auto& string : strings) {
+        memcpy(buffer, string.characters(), string.length());
+        buffer += string.length();
+    }
+    *buffer = '\0';
+    return String(move(impl));
 }
 
 }

+ 14 - 1
AK/test.cpp

@@ -10,13 +10,26 @@
 #include "Weakable.h"
 #include "WeakPtr.h"
 #include "CircularQueue.h"
+#include "FileSystemPath.h"
 
 static void testWeakPtr();
 
-int main(int, char**)
+int main(int c, char** v)
 {
     StringImpl::initializeGlobals();
 
+    {
+        const char* testpath = "/proc/../proc/1/../../proc/1/vm";
+        if (c == 2)
+            testpath = v[1];
+        FileSystemPath p(testpath);
+        if (p.string().isNull())
+            printf("canonicalized path is null\n");
+        else
+            printf("%s\n", p.string().characters());
+        return 0;
+    }
+
     {
         struct entry {
             String s;