From 4afb05d0cc35f36ea145768f052755554d9494fc Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 8 Aug 2018 17:39:00 -0400 Subject: [PATCH 1/2] fsp_srv: Emplace entries first when building index instead of emplacing last The current way were doing it would require copying a 768 character buffer (part of the Entry struct) to the new element in the vector. Given it's a plain array, std::move won't eliminate that. Instead, we can emplace an instance directly into the destination buffer and then fill it out, avoiding the need to perform any unnecessary copies. Given this is done in a loop, we can request the destination to allocate all of the necessary memory ahead of time, avoiding the need to potentially keep reallocating over and over on every few insertions into the vector. --- src/core/hle/service/filesystem/fsp_srv.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index e7ffb6bd16..4110e67b47 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -193,13 +193,14 @@ private: template static void BuildEntryIndex(std::vector& entries, const std::vector& new_data, FileSys::EntryType type) { + entries.reserve(entries.size() + new_data.size()); + for (const auto& new_entry : new_data) { - FileSys::Entry entry; + auto& entry = entries.emplace_back(); entry.filename[0] = '\0'; std::strncat(entry.filename, new_entry->GetName().c_str(), FileSys::FILENAME_LENGTH - 1); entry.type = type; entry.file_size = new_entry->GetSize(); - entries.emplace_back(std::move(entry)); } } From 7353cfc7813c960e7fdb0b33829865c606f98c84 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 8 Aug 2018 17:49:57 -0400 Subject: [PATCH 2/2] fsp_srv: Use std::string_view's copy() function instead of strncpy() Given elements inserted into a vector are zeroed out, we can just copy MAX_LEN - 1 elements and the data will already be properly null terminated. --- src/core/file_sys/directory.h | 12 +++++++++--- src/core/hle/service/filesystem/fsp_srv.cpp | 6 +----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/core/file_sys/directory.h b/src/core/file_sys/directory.h index 213ce18269..3759e743a8 100644 --- a/src/core/file_sys/directory.h +++ b/src/core/file_sys/directory.h @@ -4,8 +4,9 @@ #pragma once -#include #include +#include +#include #include "common/common_funcs.h" #include "common/common_types.h" @@ -21,9 +22,14 @@ enum EntryType : u8 { // Structure of a directory entry, from // http://switchbrew.org/index.php?title=Filesystem_services#DirectoryEntry -const size_t FILENAME_LENGTH = 0x300; struct Entry { - char filename[FILENAME_LENGTH]; + Entry(std::string_view view, EntryType entry_type, u64 entry_size) + : type{entry_type}, file_size{entry_size} { + const size_t copy_size = view.copy(filename, std::size(filename) - 1); + filename[copy_size] = '\0'; + } + + char filename[0x300]; INSERT_PADDING_BYTES(4); EntryType type; INSERT_PADDING_BYTES(3); diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 4110e67b47..1470f90175 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -196,11 +196,7 @@ static void BuildEntryIndex(std::vector& entries, const std::vec entries.reserve(entries.size() + new_data.size()); for (const auto& new_entry : new_data) { - auto& entry = entries.emplace_back(); - entry.filename[0] = '\0'; - std::strncat(entry.filename, new_entry->GetName().c_str(), FileSys::FILENAME_LENGTH - 1); - entry.type = type; - entry.file_size = new_entry->GetSize(); + entries.emplace_back(new_entry->GetName(), type, new_entry->GetSize()); } }