Implement readdir for Opera.

This commit is contained in:
2019-08-02 00:12:33 +01:00
parent 351365fc0e
commit 6f16ac55ca
2 changed files with 64 additions and 6 deletions

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Helpers;
@@ -7,7 +9,62 @@ namespace DiscImageChef.Filesystems
{
public partial class OperaFS
{
public Errno ReadDir(string path, out List<string> contents) => throw new NotImplementedException();
public Errno ReadDir(string path, out List<string> contents)
{
contents = null;
if(!mounted) return Errno.AccessDenied;
if(string.IsNullOrWhiteSpace(path) || path == "/")
{
contents = rootDirectoryCache.Keys.ToList();
return Errno.NoError;
}
string cutPath = path.StartsWith("/", StringComparison.Ordinal)
? path.Substring(1).ToLower(CultureInfo.CurrentUICulture)
: path.ToLower(CultureInfo.CurrentUICulture);
if(directoryCache.TryGetValue(cutPath, out Dictionary<string, DirectoryEntryWithPointers> currentDirectory))
{
contents = currentDirectory.Keys.ToList();
return Errno.NoError;
}
string[] pieces = cutPath.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
KeyValuePair<string, DirectoryEntryWithPointers> entry =
rootDirectoryCache.FirstOrDefault(t => t.Key.ToLower(CultureInfo.CurrentUICulture) == pieces[0]);
if(string.IsNullOrEmpty(entry.Key)) return Errno.NoSuchFile;
if((entry.Value.entry.flags & FLAGS_MASK) != (int)FileFlags.Directory) return Errno.NotDirectory;
string currentPath = pieces[0];
currentDirectory = rootDirectoryCache;
for(int p = 0; p < pieces.Length; p++)
{
entry = currentDirectory.FirstOrDefault(t => t.Key.ToLower(CultureInfo.CurrentUICulture) == pieces[p]);
if(string.IsNullOrEmpty(entry.Key)) return Errno.NoSuchFile;
if((entry.Value.entry.flags & FLAGS_MASK) != (int)FileFlags.Directory) return Errno.NotDirectory;
currentPath = p == 0 ? pieces[0] : $"{currentPath}/{pieces[p]}";
if(directoryCache.TryGetValue(currentPath, out currentDirectory)) continue;
if(entry.Value.pointers.Length < 1) return Errno.InvalidArgument;
currentDirectory = DecodeDirectory((int)entry.Value.pointers[0]);
directoryCache.Add(currentPath, currentDirectory);
}
contents = currentDirectory?.Keys.ToList();
return Errno.NoError;
}
Dictionary<string, DirectoryEntryWithPointers> DecodeDirectory(int firstBlock)
{