diff --git a/src/Aardvark.Data.Opc/Prinziple.fs b/src/Aardvark.Data.Opc/Prinziple.fs index 033dff9..9f9f262 100644 --- a/src/Aardvark.Data.Opc/Prinziple.fs +++ b/src/Aardvark.Data.Opc/Prinziple.fs @@ -105,39 +105,61 @@ module Prinziple = check 0 - member inline private x.GetEntries (predicate: string -> bool) = + member x.GetFiles(path: string, recursive: bool) = + let path = path.ToLowerInvariant() + + let isFileInPath (n: string) = + n |> String.endsWith "/" |> not && + n |> String.startsWith path && + (recursive || n.LastIndexOf('/') < path.Length) + let result = ResizeArray() for i = 0 to int zip.Count - 1 do let n = (zip.EntryByIndex i).Name - if predicate <| n.ToLowerInvariant() then + if isFileInPath <| n.ToLowerInvariant() then result.Add (Path.Combine(rootPath, n.Replace('/', dirSeparator))) for KeyValue(n, p) in additionalEntries do - if not <| result.Contains p && predicate n then + if not <| result.Contains p && isFileInPath n then result.Add p result.ToArray() - member x.GetFiles(path: string, recursive: bool) = + member x.GetDirectories(path: string) = let path = path.ToLowerInvariant() - x.GetEntries (fun n -> - n |> String.endsWith "/" |> not && - n |> String.startsWith path && - (recursive || n.LastIndexOf('/') < path.Length) - ) + let tryGetFolder (n: string) = + if n.ToLowerInvariant().StartsWith(path) && n.Length > path.Length then + let name = n.Substring path.Length + let s = name.IndexOf '/' - member x.GetDirectories(path: string) = - let path = path.ToLowerInvariant() + if s > -1 then + ValueSome <| n.Substring(0, path.Length + s + 1) + else + ValueNone + else + ValueNone - x.GetEntries (fun n -> - n |> String.endsWith "/" && - n |> String.startsWith path && - n.Length > path.Length && - n.Substring(0, n.Length - 1).LastIndexOf('/') < path.Length - ) + let result = HashSet() + + let addEntry (n: string) = + match tryGetFolder n with + | ValueSome n -> + let p = Path.Combine(rootPath, n.Replace('/', dirSeparator)) + result.Add p |> ignore + + | _ -> () + + for i = 0 to int zip.Count - 1 do + let n = (zip.EntryByIndex i).Name + addEntry n + + for KeyValue(n, _) in additionalEntries do + addEntry n + + result.ToArray(result.Count) member x.Commit(compress: bool) = if not additionalEntries.IsEmpty then diff --git a/src/Tests/FSharpTests/FSharpTests.fsproj b/src/Tests/FSharpTests/FSharpTests.fsproj index 3c285d7..4e10b31 100644 --- a/src/Tests/FSharpTests/FSharpTests.fsproj +++ b/src/Tests/FSharpTests/FSharpTests.fsproj @@ -7,6 +7,7 @@ + @@ -14,7 +15,6 @@ - diff --git a/src/Tests/FSharpTests/OpcTests.fs b/src/Tests/FSharpTests/OpcTests.fs index 9a2a1f1..acfcef9 100644 --- a/src/Tests/FSharpTests/OpcTests.fs +++ b/src/Tests/FSharpTests/OpcTests.fs @@ -9,25 +9,42 @@ open System.Threading.Tasks open NUnit.Framework open FsUnit +[] +type ZipKind = + | ImplicitDirs + | ExplicitDirs + +[] +type GetFilesMode = + | Recursive + | TopLevel + module Prinziple = - let private rootPath = Path.Combine(__SOURCE_DIRECTORY__, "data", "opc", "test") + let private getRootPath (zipKind: ZipKind) = + let file = if zipKind = ImplicitDirs then "test_implicit_dirs" else "test" + Path.Combine(__SOURCE_DIRECTORY__, "data", "opc", file) + + let private ZipKindSource = [| ImplicitDirs; ExplicitDirs |] + let private GetFilesModeSource = [| Recursive; TopLevel |] [] - let fileExists() = + let fileExists ([] zipKind: ZipKind) = + let rootPath = getRootPath zipKind Prinziple.tryRegister rootPath |> should be True [rootPath; "files"; "nested"; "g.txt"] |> Path.combine |> Prinziple.fileExists |> should be True [rootPath; "files"; "nested"] |> Path.combine |> Prinziple.fileExists |> should be False [] - let directoryExists() = + let directoryExists([] zipKind: ZipKind) = + let rootPath = getRootPath zipKind Prinziple.tryRegister rootPath |> should be True [rootPath; "files"; "nested"; "g.txt"] |> Path.combine |> Prinziple.directoryExists |> should be False [rootPath; "files"; "nested"] |> Path.combine |> Prinziple.directoryExists |> should be True - [] - [] - let getFiles (recursive: bool) = + [] + let getFiles ([] mode: GetFilesMode) ([] zipKind: ZipKind) = + let rootPath = getRootPath zipKind Prinziple.tryRegister rootPath |> should be True let expected = @@ -37,21 +54,22 @@ module Prinziple = "files/c.txt" "files/d.txt" "files/e.txt" - if recursive then "files/more/f.txt" - if recursive then "files/nested/g.txt" + if mode = Recursive then "files/more/f.txt" + if mode = Recursive then "files/nested/g.txt" |] |> Array.map (fun f -> Path.Combine(rootPath, f) |> Path.GetFullPath) |> Array.sort let files = Path.combine [rootPath; "files"] - |> Prinziple.getFiles recursive + |> Prinziple.getFiles (mode = Recursive) |> Array.sort files |> should equal expected [] - let getDirectories() = + let getDirectories ([] zipKind: ZipKind) = + let rootPath = getRootPath zipKind Prinziple.tryRegister rootPath |> should be True let expected = @@ -70,14 +88,16 @@ module Prinziple = dirs |> should equal expected [] - let reading() = + let reading ([] zipKind: ZipKind) = + let rootPath = getRootPath zipKind Prinziple.tryRegister rootPath |> should be True let path = Path.combine [rootPath; "files"; "a.txt"] Prinziple.readAllText path |> should equal "TEST" [] - let ``concurrent I/O``() = + let ``concurrent I/O`` ([] zipKind: ZipKind) = + let rootPath = getRootPath zipKind Prinziple.tryRegister rootPath |> should be True try @@ -127,7 +147,8 @@ module Prinziple = Directory.Delete(rootPath, true) [] - let writing() = + let writing ([] zipKind: ZipKind) = + let rootPath = getRootPath zipKind Prinziple.tryRegister rootPath |> should be True let path = Path.combine [rootPath; "files"; "new.txt"] @@ -145,7 +166,8 @@ module Prinziple = Directory.Delete(rootPath, true) [] - let commit() = + let commit ([] zipKind: ZipKind) = + let rootPath = getRootPath zipKind let tempRootPath = rootPath + "_temp" let tempRootZip = Path.ChangeExtension(tempRootPath, ".zip") diff --git a/src/Tests/FSharpTests/data/opc/test_implicit_dirs.zip b/src/Tests/FSharpTests/data/opc/test_implicit_dirs.zip new file mode 100644 index 0000000..5e1bf23 Binary files /dev/null and b/src/Tests/FSharpTests/data/opc/test_implicit_dirs.zip differ