1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 00:38:11 +00:00

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

This commit is contained in:
Andreas Kling 2019-01-28 22:55:55 +01:00
parent f83a94ca39
commit cc906a2897
3 changed files with 20 additions and 8 deletions

View file

@ -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);

View file

@ -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();

View file

@ -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); builder.append((const char*)buffer, nread);
out += 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 builder.to_byte_buffer();
return contents;
} }
FS::DirectoryEntry::DirectoryEntry(const char* n, InodeIdentifier i, byte ft) FS::DirectoryEntry::DirectoryEntry(const char* n, InodeIdentifier i, byte ft)