Skip to content

Commit

Permalink
Remove extern
Browse files Browse the repository at this point in the history
  • Loading branch information
madhurajayaraman committed May 28, 2024
1 parent 3d9fb01 commit 8ec261f
Showing 1 changed file with 51 additions and 42 deletions.
93 changes: 51 additions & 42 deletions starboard/shared/win32/posix_emu/dirent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
#include "starboard/shared/win32/wchar_utils.h"
#include "starboard/types.h"

extern "C" {

struct CriticalSection {
CriticalSection() { InitializeCriticalSection(&critical_section_); }
CRITICAL_SECTION critical_section_;
Expand Down Expand Up @@ -97,6 +95,50 @@ void handle_db_replace(int fd, std::deque<std::string> next_directory_entry) {
LeaveCriticalSection(&g_critical_section.critical_section_);
}

std::deque<std::string> GetDirectoryEntries(HANDLE directory_handle) {
// According to
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364226(v=vs.85).aspx,
// FILE_ID_BOTH_DIR_INFO must be aligned on a DWORDLONG boundary.
const std::size_t kDirectoryInfoBufferSize =
kSbFileMaxPath + sizeof(FILE_ID_BOTH_DIR_INFO);
alignas(sizeof(DWORDLONG)) std::vector<char> directory_info_buffer(
kDirectoryInfoBufferSize);

std::deque<std::string> entries;
BOOL directory_info_success = GetFileInformationByHandleEx(
directory_handle, FileIdBothDirectoryInfo, directory_info_buffer.data(),
static_cast<int>(directory_info_buffer.size()));

if (!directory_info_success) {
return entries;
}

const char* directory_info_pointer = directory_info_buffer.data();
DWORD next_entry_offset = 0;

do {
auto directory_info =
reinterpret_cast<const FILE_ID_BOTH_DIR_INFO*>(directory_info_pointer);

// FileName is in Unicode, so divide by 2 to get the real length.
DWORD number_characters_in_filename = directory_info->FileNameLength / 2;
std::string ascii_path = starboard::shared::win32::wchar_tToUTF8(
directory_info->FileName, number_characters_in_filename);
SB_DCHECK(ascii_path.size() == number_characters_in_filename);
bool is_dotted_directory =
!ascii_path.compare(".") || !ascii_path.compare("..");
if (!is_dotted_directory) {
entries.emplace_back(std::move(ascii_path));
}
next_entry_offset = directory_info->NextEntryOffset;
directory_info_pointer += next_entry_offset;
} while (next_entry_offset != 0);

return entries;
}

extern "C" {

DIR* opendir(const char* path) {
using starboard::shared::win32::CStringToWString;
using starboard::shared::win32::NormalizeWin32Path;
Expand Down Expand Up @@ -142,10 +184,6 @@ int closedir(DIR* dir) {
return success ? 0 : -1;
}

// One of the entries of FILE_ID_BOTH_DIR_INFO is a file path, so make the
// buffer at-least one path big.
const std::size_t kDirectoryInfoBufferSize =
kSbFileMaxPath + sizeof(FILE_ID_BOTH_DIR_INFO);

int readdir_r(DIR* __restrict dir,
struct dirent* __restrict dirent_buf,
Expand All @@ -154,51 +192,22 @@ int readdir_r(DIR* __restrict dir,
return -1;
}

std::deque<std::string> next_directory_entries = handle_db_get(dir->fd, false);
if (next_directory_entries.empty()){
alignas(sizeof(DWORDLONG)) std::vector<char> directory_info_buffer(
kDirectoryInfoBufferSize);
BOOL directory_info_success = GetFileInformationByHandleEx(
dir->handle, FileIdBothDirectoryInfo, directory_info_buffer.data(),
static_cast<int>(directory_info_buffer.size()));

if (!directory_info_success) {
return -1;
}

const char* directory_info_pointer = directory_info_buffer.data();
DWORD next_entry_offset = 0;

do {
auto directory_info = reinterpret_cast<const FILE_ID_BOTH_DIR_INFO*>(
directory_info_pointer);

// FileName is in Unicode, so divide by 2 to get the real length.
DWORD number_characters_in_filename = directory_info->FileNameLength / 2;
std::string ascii_path = starboard::shared::win32::wchar_tToUTF8(
directory_info->FileName, number_characters_in_filename);
SB_DCHECK(ascii_path.size() == number_characters_in_filename);
bool is_dotted_directory =
!ascii_path.compare(".") || !ascii_path.compare("..");
if (!is_dotted_directory) {
next_directory_entries.emplace_back(std::move(ascii_path));
}
next_entry_offset = directory_info->NextEntryOffset;
directory_info_pointer += next_entry_offset;
} while (next_entry_offset != 0);
handle_db_replace(dir->fd, next_directory_entries);
auto& next_directory_entries = handle_db_get(dir->fd, false);
if (next_directory_entries.empty()) {
next_directory_entries = GetDirectoryEntries(dir->handle);
}


if (next_directory_entries.empty()) {
return -1;
}

int res = starboard::strlcpy(dirent_buf->d_name, next_directory_entries.rbegin()->c_str(), kSbFileMaxName);
if (res >= kSbFileMaxName) {
if (starboard::strlcpy(dirent_buf->d_name, next_directory_entries.rbegin()->c_str(),
kSbFileMaxName) >= kSbFileMaxName) {
return -1;
}
*dirent = dirent_buf;
next_directory_entries.pop_back();
handle_db_replace(dir->fd, next_directory_entries);

return 0;
}
Expand Down

0 comments on commit 8ec261f

Please sign in to comment.