drive iteration in win32 file system api; fix some root-level behaviors of file browser

This commit is contained in:
Ryan Fleury
2024-05-31 12:20:14 -07:00
parent d3adfdeced
commit 59e71eb5cc
6 changed files with 101 additions and 60 deletions
+3 -3
View File
@@ -946,11 +946,11 @@ str8_array_from_list(Arena *arena, String8List *list)
{
String8Array array;
array.count = list->node_count;
array.strings = push_array_no_zero(arena, String8, array.count);
array.v = push_array_no_zero(arena, String8, array.count);
U64 idx = 0;
for(String8Node *n = list->first; n != 0; n = n->next, idx += 1)
{
array.strings[idx] = n->string;
array.v[idx] = n->string;
}
return array;
}
@@ -960,7 +960,7 @@ str8_array_reserve(Arena *arena, U64 count)
{
String8Array arr;
arr.count = 0;
arr.strings = push_array(arena, String8, count);
arr.v = push_array(arena, String8, count);
return arr;
}
+1 -1
View File
@@ -63,7 +63,7 @@ struct String8List
typedef struct String8Array String8Array;
struct String8Array
{
String8 *strings;
String8 *v;
U64 count;
};
+5 -8
View File
@@ -2811,12 +2811,9 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem)
if(ui_clicked(sig))
{
String8 new_path = str8_chop_last_slash(str8_chop_last_slash(path_query.path));
if(new_path.size != 0)
{
new_path = path_normalized_from_string(scratch.arena, new_path);
String8 new_cmd = push_str8f(scratch.arena, "%S/", new_path);
df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node);
}
new_path = path_normalized_from_string(scratch.arena, new_path);
String8 new_cmd = push_str8f(scratch.arena, "%S%s", new_path, new_path.size != 0 ? "/" : "");
df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node);
}
}
@@ -2893,11 +2890,11 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem)
if(ui_clicked(file_sig))
{
String8 existing_path = str8_chop_last_slash(path_query.path);
String8 new_path = push_str8f(scratch.arena, "%S/%S/", existing_path, file->filename);
String8 new_path = push_str8f(scratch.arena, "%S%s%S/", existing_path, existing_path.size != 0 ? "/" : "", file->filename);
new_path = path_normalized_from_string(scratch.arena, new_path);
if(file->props.flags & FilePropertyFlag_IsFolder)
{
String8 new_cmd = push_str8f(scratch.arena, "%S/", new_path);
String8 new_cmd = push_str8f(scratch.arena, "%S%s", new_path, new_path.size != 0 ? "/" : "");
df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node);
}
else
+1 -1
View File
@@ -34,7 +34,7 @@ typedef struct OS_FileIter OS_FileIter;
struct OS_FileIter
{
OS_FileIterFlags flags;
U8 memory[600];
U8 memory[800];
};
typedef struct OS_FileInfo OS_FileInfo;
+88 -47
View File
@@ -198,7 +198,7 @@ os_init(void)
w32_VirtualAlloc2_func = (W32_VirtualAlloc2_Type*)GetProcAddress(module, "VirtualAlloc2");
w32_MapViewOfFile3_func = (W32_MapViewOfFile3_Type*)GetProcAddress(module, "MapViewOfFile3");
w32_SetThreadDescription_func = (W32_SetThreadDescription_Type*)GetProcAddress(module, "SetThreadDescription");
FreeLibrary(module);
}
}
@@ -964,7 +964,27 @@ os_file_iter_begin(Arena *arena, String8 path, OS_FileIterFlags flags)
OS_FileIter *iter = push_array(arena, OS_FileIter, 1);
iter->flags = flags;
W32_FileIter *w32_iter = (W32_FileIter*)iter->memory;
w32_iter->handle = FindFirstFileW((WCHAR*)path16.str, &w32_iter->find_data);
if(path.size == 0)
{
w32_iter->is_volume_iter = 1;
WCHAR buffer[512] = {0};
DWORD length = GetLogicalDriveStringsW(sizeof(buffer), buffer);
String8List drive_strings = {0};
for(U64 off = 0; off < (U64)length;)
{
String16 next_drive_string_16 = str16_cstring((U16 *)buffer+off);
off += next_drive_string_16.size+1;
String8 next_drive_string = str8_from_16(arena, next_drive_string_16);
next_drive_string = str8_chop_last_slash(next_drive_string);
str8_list_push(scratch.arena, &drive_strings, next_drive_string);
}
w32_iter->drive_strings = str8_array_from_list(arena, &drive_strings);
w32_iter->drive_strings_iter_idx = 0;
}
else
{
w32_iter->handle = FindFirstFileW((WCHAR*)path16.str, &w32_iter->find_data);
}
scratch_end(scratch);
return iter;
}
@@ -975,55 +995,76 @@ os_file_iter_next(Arena *arena, OS_FileIter *iter, OS_FileInfo *info_out)
B32 result = 0;
OS_FileIterFlags flags = iter->flags;
W32_FileIter *w32_iter = (W32_FileIter*)iter->memory;
if (!(flags & OS_FileIterFlag_Done) && w32_iter->handle != INVALID_HANDLE_VALUE)
switch(w32_iter->is_volume_iter)
{
do
//- rjf: file iteration
default:
case 0:
{
// check is usable
B32 usable_file = 1;
WCHAR *file_name = w32_iter->find_data.cFileName;
DWORD attributes = w32_iter->find_data.dwFileAttributes;
if (file_name[0] == '.'){
if (flags & OS_FileIterFlag_SkipHiddenFiles){
usable_file = 0;
}
else if (file_name[1] == 0){
usable_file = 0;
}
else if (file_name[1] == '.' && file_name[2] == 0){
usable_file = 0;
}
if (!(flags & OS_FileIterFlag_Done) && w32_iter->handle != INVALID_HANDLE_VALUE)
{
do
{
// check is usable
B32 usable_file = 1;
WCHAR *file_name = w32_iter->find_data.cFileName;
DWORD attributes = w32_iter->find_data.dwFileAttributes;
if (file_name[0] == '.'){
if (flags & OS_FileIterFlag_SkipHiddenFiles){
usable_file = 0;
}
else if (file_name[1] == 0){
usable_file = 0;
}
else if (file_name[1] == '.' && file_name[2] == 0){
usable_file = 0;
}
}
if (attributes & FILE_ATTRIBUTE_DIRECTORY){
if (flags & OS_FileIterFlag_SkipFolders){
usable_file = 0;
}
}
else{
if (flags & OS_FileIterFlag_SkipFiles){
usable_file = 0;
}
}
// emit if usable
if (usable_file){
info_out->name = str8_from_16(arena, str16_cstring((U16*)file_name));
info_out->props.size = (U64)w32_iter->find_data.nFileSizeLow | (((U64)w32_iter->find_data.nFileSizeHigh)<<32);
w32_dense_time_from_file_time(&info_out->props.created, &w32_iter->find_data.ftCreationTime);
w32_dense_time_from_file_time(&info_out->props.modified, &w32_iter->find_data.ftLastWriteTime);
info_out->props.flags = w32_file_property_flags_from_dwFileAttributes(attributes);
result = 1;
if (!FindNextFileW(w32_iter->handle, &w32_iter->find_data)){
iter->flags |= OS_FileIterFlag_Done;
}
break;
}
}while(FindNextFileW(w32_iter->handle, &w32_iter->find_data));
}
if (attributes & FILE_ATTRIBUTE_DIRECTORY){
if (flags & OS_FileIterFlag_SkipFolders){
usable_file = 0;
}
}
else{
if (flags & OS_FileIterFlag_SkipFiles){
usable_file = 0;
}
}
// emit if usable
if (usable_file){
info_out->name = str8_from_16(arena, str16_cstring((U16*)file_name));
info_out->props.size = (U64)w32_iter->find_data.nFileSizeLow | (((U64)w32_iter->find_data.nFileSizeHigh)<<32);
w32_dense_time_from_file_time(&info_out->props.created, &w32_iter->find_data.ftCreationTime);
w32_dense_time_from_file_time(&info_out->props.modified, &w32_iter->find_data.ftLastWriteTime);
info_out->props.flags = w32_file_property_flags_from_dwFileAttributes(attributes);
result = 1;
if (!FindNextFileW(w32_iter->handle, &w32_iter->find_data)){
iter->flags |= OS_FileIterFlag_Done;
}
break;
}
}while(FindNextFileW(w32_iter->handle, &w32_iter->find_data));
}break;
if (!result){
iter->flags |= OS_FileIterFlag_Done;
}
//- rjf: volume iteration
case 1:
{
result = w32_iter->drive_strings_iter_idx < w32_iter->drive_strings.count;
if(result != 0)
{
MemoryZeroStruct(info_out);
info_out->name = w32_iter->drive_strings.v[w32_iter->drive_strings_iter_idx];
info_out->props.flags |= FilePropertyFlag_IsFolder;
w32_iter->drive_strings_iter_idx += 1;
}
}break;
}
if(!result)
{
iter->flags |= OS_FileIterFlag_Done;
}
return result;
}
+3
View File
@@ -23,6 +23,9 @@ struct W32_FileIter
{
HANDLE handle;
WIN32_FIND_DATAW find_data;
B32 is_volume_iter;
String8Array drive_strings;
U64 drive_strings_iter_idx;
};
StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(W32_FileIter), file_iter_memory_size);