Ver código fonte

VFS: Resolve FIXME in Inode::read_entire() about using dynamic allocation.

Andreas Kling 6 anos atrás
pai
commit
cc906a2897
3 arquivos alterados com 20 adições e 8 exclusões
  1. 14 0
      AK/StringBuilder.cpp
  2. 2 1
      AK/StringBuilder.h
  3. 4 7
      Kernel/FileSystem.cpp

+ 14 - 0
AK/StringBuilder.cpp

@@ -11,6 +11,11 @@ inline void StringBuilder::will_append(size_t size)
         m_buffer.grow(max(16u, m_buffer.size() * 2 + size));
         m_buffer.grow(max(16u, m_buffer.size() * 2 + size));
 }
 }
 
 
+StringBuilder::StringBuilder(size_t initial_capacity)
+{
+    m_buffer.grow(initial_capacity);
+}
+
 void StringBuilder::append(const String& str)
 void StringBuilder::append(const String& str)
 {
 {
     if (str.is_empty())
     if (str.is_empty())
@@ -20,6 +25,15 @@ void StringBuilder::append(const String& str)
     m_length += str.length();
     m_length += str.length();
 }
 }
 
 
+void StringBuilder::append(const char* characters, size_t length)
+{
+    if (!length)
+        return;
+    will_append(length);
+    memcpy(m_buffer.pointer() + m_length, characters, length);
+    m_length += length;
+}
+
 void StringBuilder::append(char ch)
 void StringBuilder::append(char ch)
 {
 {
     will_append(1);
     will_append(1);

+ 2 - 1
AK/StringBuilder.h

@@ -7,11 +7,12 @@ namespace AK {
 
 
 class StringBuilder {
 class StringBuilder {
 public:
 public:
-    StringBuilder() { }
+    explicit StringBuilder(size_t initial_capacity = 16);
     ~StringBuilder() { }
     ~StringBuilder() { }
 
 
     void append(const String&);
     void append(const String&);
     void append(char);
     void append(char);
+    void append(const char*, size_t);
     void appendf(const char*, ...);
     void appendf(const char*, ...);
 
 
     String build();
     String build();

+ 4 - 7
Kernel/FileSystem.cpp

@@ -1,5 +1,6 @@
 #include <AK/Assertions.h>
 #include <AK/Assertions.h>
 #include <AK/HashMap.h>
 #include <AK/HashMap.h>
+#include <AK/StringBuilder.h>
 #include <LibC/errno_numbers.h>
 #include <LibC/errno_numbers.h>
 #include "FileSystem.h"
 #include "FileSystem.h"
 #include "MemoryManager.h"
 #include "MemoryManager.h"
@@ -51,29 +52,25 @@ FS* FS::from_fsid(dword id)
 ByteBuffer Inode::read_entire(FileDescriptor* descriptor) const
 ByteBuffer Inode::read_entire(FileDescriptor* descriptor) const
 {
 {
     size_t initial_size = metadata().size ? metadata().size : 4096;
     size_t initial_size = metadata().size ? metadata().size : 4096;
-    auto contents = ByteBuffer::create_uninitialized(initial_size);
+    StringBuilder builder(initial_size);
 
 
     ssize_t nread;
     ssize_t nread;
     byte buffer[4096];
     byte buffer[4096];
-    byte* out = contents.pointer();
     off_t offset = 0;
     off_t offset = 0;
     for (;;) {
     for (;;) {
         nread = read_bytes(offset, sizeof(buffer), buffer, descriptor);
         nread = read_bytes(offset, sizeof(buffer), buffer, descriptor);
         ASSERT(nread <= (ssize_t)sizeof(buffer));
         ASSERT(nread <= (ssize_t)sizeof(buffer));
         if (nread <= 0)
         if (nread <= 0)
             break;
             break;
-        memcpy(out, buffer, nread);
-        out += nread;
+        builder.append((const char*)buffer, nread);
         offset += nread;
         offset += nread;
-        ASSERT(offset <= (ssize_t)initial_size); // FIXME: Support dynamically growing the buffer.
     }
     }
     if (nread < 0) {
     if (nread < 0) {
         kprintf("Inode::read_entire: ERROR: %d\n", nread);
         kprintf("Inode::read_entire: ERROR: %d\n", nread);
         return nullptr;
         return nullptr;
     }
     }
 
 
-    contents.trim(offset);
-    return contents;
+    return builder.to_byte_buffer();
 }
 }
 
 
 FS::DirectoryEntry::DirectoryEntry(const char* n, InodeIdentifier i, byte ft)
 FS::DirectoryEntry::DirectoryEntry(const char* n, InodeIdentifier i, byte ft)