diff --git a/SharpFileSystem.Tests/NetZipArchive/NetZipArchiveFileSystemTest.cs b/SharpFileSystem.Tests/NetZipArchive/NetZipArchiveFileSystemTest.cs
new file mode 100644
index 0000000..3af08d5
--- /dev/null
+++ b/SharpFileSystem.Tests/NetZipArchive/NetZipArchiveFileSystemTest.cs
@@ -0,0 +1,132 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using ICSharpCode.SharpZipLib.Zip;
+using NUnit.Framework;
+using SharpFileSystem.IO;
+using SharpFileSystem.SharpZipArchive;
+
+namespace SharpFileSystem.Tests.NetZipArchive
+{
+ [TestFixture]
+ public class NetZipArchiveFileSystemTest
+ {
+ private Stream zipStream;
+ private NetZipArchiveFileSystem fileSystem;
+ private string fileContentString = "this is a file";
+ [OneTimeSetUp]
+ public void Initialize()
+ {
+ var memoryStream = new MemoryStream();
+ zipStream = memoryStream;
+ var zipOutput = new ZipOutputStream(zipStream);
+
+
+ var fileContentBytes = Encoding.ASCII.GetBytes(fileContentString);
+ zipOutput.PutNextEntry(new ZipEntry("textfileA.txt")
+ {
+ Size = fileContentBytes.Length
+ });
+ zipOutput.Write(fileContentBytes);
+ zipOutput.PutNextEntry(new ZipEntry("directory/fileInDirectory.txt"));
+ zipOutput.PutNextEntry(new ZipEntry("scratchdirectory/scratch"));
+ zipOutput.Finish();
+
+ memoryStream.Position = 0;
+ fileSystem = NetZipArchiveFileSystem.Open(zipStream);
+ }
+
+ [OneTimeTearDown]
+ public void Cleanup()
+ {
+ fileSystem.Dispose();
+ zipStream.Dispose();
+ }
+
+ private readonly FileSystemPath directoryPath = FileSystemPath.Parse("/directory/");
+ private readonly FileSystemPath textfileAPath = FileSystemPath.Parse("/textfileA.txt");
+ private readonly FileSystemPath fileInDirectoryPath = FileSystemPath.Parse("/directory/fileInDirectory.txt");
+ private readonly FileSystemPath scratchDirectoryPath = FileSystemPath.Parse("/scratchdirectory/");
+
+ [Test]
+ public void GetEntitiesOfRootTest()
+ {
+ CollectionAssert.AreEquivalent(new[]
+ {
+ textfileAPath,
+ directoryPath,
+ scratchDirectoryPath
+ }, fileSystem.GetEntities(FileSystemPath.Root).ToArray());
+ }
+
+ [Test]
+ public void GetEntitiesOfDirectoryTest()
+ {
+ CollectionAssert.AreEquivalent(new[]
+ {
+ fileInDirectoryPath
+ }, fileSystem.GetEntities(directoryPath).ToArray());
+ }
+
+ [Test]
+ public void ExistsTest()
+ {
+ Assert.IsTrue(fileSystem.Exists(FileSystemPath.Root));
+ Assert.IsTrue(fileSystem.Exists(textfileAPath));
+ Assert.IsTrue(fileSystem.Exists(directoryPath));
+ Assert.IsTrue(fileSystem.Exists(fileInDirectoryPath));
+ Assert.IsFalse(fileSystem.Exists(FileSystemPath.Parse("/nonExistingFile")));
+ Assert.IsFalse(fileSystem.Exists(FileSystemPath.Parse("/nonExistingDirectory/")));
+ Assert.IsFalse(fileSystem.Exists(FileSystemPath.Parse("/directory/nonExistingFileInDirectory")));
+ }
+
+ [Test]
+ public void CanReadFile()
+ {
+ var file = fileSystem.OpenFile(textfileAPath, FileAccess.ReadWrite);
+ var text = file.ReadAllText();
+ Assert.IsTrue(string.Equals(text, fileContentString));
+ }
+
+ [Test]
+ public void CanWriteFile()
+ {
+ var file = fileSystem.OpenFile(textfileAPath, FileAccess.ReadWrite);
+ var textBytes = Encoding.ASCII.GetBytes(fileContentString + " and a new string");
+ file.Write(textBytes);
+ file.Close();
+
+
+ file = fileSystem.OpenFile(textfileAPath, FileAccess.ReadWrite);
+ var text = file.ReadAllText();
+ Assert.IsTrue(string.Equals(text, fileContentString + " and a new string"));
+ }
+
+ [Test]
+ public void CanAddFile()
+ {
+ var fsp = FileSystemPath.Parse("/scratchdirectory/recentlyadded.txt");
+ var file = fileSystem.CreateFile(fsp);
+ var textBytes = Encoding.ASCII.GetBytes("recently added");
+ file.Write(textBytes);
+ file.Close();
+
+ Assert.IsTrue(fileSystem.Exists(fsp));
+
+ file = fileSystem.OpenFile(fsp, FileAccess.ReadWrite);
+ var text = file.ReadAllText();
+ Assert.IsTrue(string.Equals(text, "recently added"));
+ }
+
+ [Test]
+ public void CanAddDirectory()
+ {
+ var fsp = FileSystemPath.Parse("/scratchdirectory/newdir/");
+ fileSystem.CreateDirectory(fsp);
+
+ Assert.IsTrue(fileSystem.Exists(fsp));
+ }
+ }
+}
diff --git a/SharpFileSystem.Tests/SharpFileSystem.Tests.csproj b/SharpFileSystem.Tests/SharpFileSystem.Tests.csproj
index 606a39c..ad9b564 100644
--- a/SharpFileSystem.Tests/SharpFileSystem.Tests.csproj
+++ b/SharpFileSystem.Tests/SharpFileSystem.Tests.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -43,12 +43,17 @@
+
+
+ {8d44f07f-a1f8-4544-8eef-b2fd99d0fba2}
+ SharpFileSystem.NetZipArchive
+
{3C4D07BA-23B5-4A63-92CF-F3BF892B7329}
SharpFileSystem
@@ -72,4 +77,4 @@
-
+
\ No newline at end of file
diff --git a/SharpFileSystem.ZipArchive/NetZipArchiveFileSystem.cs b/SharpFileSystem.ZipArchive/NetZipArchiveFileSystem.cs
new file mode 100644
index 0000000..139611b
--- /dev/null
+++ b/SharpFileSystem.ZipArchive/NetZipArchiveFileSystem.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.IO.Compression;
+
+namespace SharpFileSystem.SharpZipArchive
+{
+ public class NetZipArchiveFileSystem : IFileSystem
+ {
+ public ZipArchive ZipArchive { get; private set; }
+
+ public static NetZipArchiveFileSystem Open(Stream s)
+ {
+ return new NetZipArchiveFileSystem(new ZipArchive(s,ZipArchiveMode.Update,true));
+ }
+
+ public static NetZipArchiveFileSystem Create(Stream s)
+ {
+ return new NetZipArchiveFileSystem(new ZipArchive(s, ZipArchiveMode.Create, true));
+ }
+
+ private NetZipArchiveFileSystem(ZipArchive archive)
+ {
+ ZipArchive = archive;
+ }
+ public void Dispose()
+ {
+ ZipArchive.Dispose();
+ }
+
+ protected IEnumerable GetZipEntries()
+ {
+ return ZipArchive.Entries;
+ }
+ protected FileSystemPath ToPath(ZipArchiveEntry entry)
+ {
+ return FileSystemPath.Parse(FileSystemPath.DirectorySeparator + entry.FullName);
+ }
+ protected string ToEntryPath(FileSystemPath path)
+ {
+ // Remove heading '/' from path.
+ return path.Path.TrimStart(FileSystemPath.DirectorySeparator);
+ }
+
+ protected ZipArchiveEntry ToEntry(FileSystemPath path)
+ {
+ return ZipArchive.GetEntry(ToEntryPath(path));
+ }
+ public ICollection GetEntities(FileSystemPath path)
+ {
+ return GetZipEntries().Select(ToPath).Where(path.IsParentOf)
+ .Select(entryPath => entryPath.ParentPath == path
+ ? entryPath
+ : path.AppendDirectory(entryPath.RemoveParent(path).GetDirectorySegments()[0])
+ )
+ .Distinct()
+ .ToList();
+ }
+
+ public bool Exists(FileSystemPath path)
+ {
+ if (path.IsFile)
+ return ToEntry(path) != null;
+ return GetZipEntries()
+ .Select(ToPath)
+ .Any(entryPath => entryPath.IsChildOf(path));
+
+ //foreach (var zipArchiveEntry in GetZipEntries())
+ //{
+ // var p = ToPath(zipArchiveEntry);
+ // if(p.IsChildOf(path) )
+ // return true;
+ //}
+ //return false;
+ }
+
+ public Stream CreateFile(FileSystemPath path)
+ {
+ var zae = ZipArchive.CreateEntry(ToEntryPath(path));
+ return zae.Open();
+ }
+
+ public Stream OpenFile(FileSystemPath path, FileAccess access)
+ {
+ var zae = ZipArchive.GetEntry(ToEntryPath(path));
+ return zae.Open();
+ }
+
+ public void CreateDirectory(FileSystemPath path)
+ {
+ ZipArchive.CreateEntry(ToEntryPath(path));
+ }
+
+ public void Delete(FileSystemPath path)
+ {
+ var zae = ZipArchive.GetEntry(ToEntryPath(path));
+ zae.Delete();
+ }
+ }
+}
diff --git a/SharpFileSystem.ZipArchive/Properties/AssemblyInfo.cs b/SharpFileSystem.ZipArchive/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..58a4df8
--- /dev/null
+++ b/SharpFileSystem.ZipArchive/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("SharpFileSystem.ZipArchive")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SharpFileSystem.ZipArchive")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("8d44f07f-a1f8-4544-8eef-b2fd99d0fba2")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/SharpFileSystem.ZipArchive/SharpFileSystem.NetZipArchive.csproj b/SharpFileSystem.ZipArchive/SharpFileSystem.NetZipArchive.csproj
new file mode 100644
index 0000000..3fd8173
--- /dev/null
+++ b/SharpFileSystem.ZipArchive/SharpFileSystem.NetZipArchive.csproj
@@ -0,0 +1,56 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {8D44F07F-A1F8-4544-8EEF-B2FD99D0FBA2}
+ Library
+ Properties
+ SharpFileSystem.SharpZipArchive
+ SharpFileSystem.SharpZipArchive
+ v4.5
+ 512
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {3C4D07BA-23B5-4A63-92CF-F3BF892B7329}
+ SharpFileSystem
+
+
+
+
\ No newline at end of file
diff --git a/SharpFileSystem.sln b/SharpFileSystem.sln
index aca9579..9df2031 100644
--- a/SharpFileSystem.sln
+++ b/SharpFileSystem.sln
@@ -1,7 +1,6 @@
-
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-VisualStudioVersion = 14.0.23107.0
+# Visual Studio 15
+VisualStudioVersion = 15.0.26228.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0F7EEFA8-7215-406A-9353-849DF790CAA0}"
EndProject
@@ -15,38 +14,45 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpFileSystem.SharpZipLib
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpFileSystem.Tests", "SharpFileSystem.Tests\SharpFileSystem.Tests.csproj", "{5B828500-C591-4B35-AFB2-D38026A7ECBC}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpFileSystem.NetZipArchive", "SharpFileSystem.ZipArchive\SharpFileSystem.NetZipArchive.csproj", "{8D44F07F-A1F8-4544-8EEF-B2FD99D0FBA2}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {34CA60AC-D3A0-4A58-BCE1-3CEA55844715}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {34CA60AC-D3A0-4A58-BCE1-3CEA55844715}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {34CA60AC-D3A0-4A58-BCE1-3CEA55844715}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {34CA60AC-D3A0-4A58-BCE1-3CEA55844715}.Release|Any CPU.Build.0 = Release|Any CPU
{3C4D07BA-23B5-4A63-92CF-F3BF892B7329}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C4D07BA-23B5-4A63-92CF-F3BF892B7329}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C4D07BA-23B5-4A63-92CF-F3BF892B7329}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C4D07BA-23B5-4A63-92CF-F3BF892B7329}.Release|Any CPU.Build.0 = Release|Any CPU
- {5B828500-C591-4B35-AFB2-D38026A7ECBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5B828500-C591-4B35-AFB2-D38026A7ECBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5B828500-C591-4B35-AFB2-D38026A7ECBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5B828500-C591-4B35-AFB2-D38026A7ECBC}.Release|Any CPU.Build.0 = Release|Any CPU
- {E0BAC37A-07E5-4192-8BD9-51C7CA66C165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E0BAC37A-07E5-4192-8BD9-51C7CA66C165}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E0BAC37A-07E5-4192-8BD9-51C7CA66C165}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E0BAC37A-07E5-4192-8BD9-51C7CA66C165}.Release|Any CPU.Build.0 = Release|Any CPU
{EA7CBA29-CFA8-4945-BB64-CCF25078190E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EA7CBA29-CFA8-4945-BB64-CCF25078190E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EA7CBA29-CFA8-4945-BB64-CCF25078190E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EA7CBA29-CFA8-4945-BB64-CCF25078190E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {34CA60AC-D3A0-4A58-BCE1-3CEA55844715}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {34CA60AC-D3A0-4A58-BCE1-3CEA55844715}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {34CA60AC-D3A0-4A58-BCE1-3CEA55844715}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {34CA60AC-D3A0-4A58-BCE1-3CEA55844715}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E0BAC37A-07E5-4192-8BD9-51C7CA66C165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E0BAC37A-07E5-4192-8BD9-51C7CA66C165}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E0BAC37A-07E5-4192-8BD9-51C7CA66C165}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E0BAC37A-07E5-4192-8BD9-51C7CA66C165}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5B828500-C591-4B35-AFB2-D38026A7ECBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5B828500-C591-4B35-AFB2-D38026A7ECBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B828500-C591-4B35-AFB2-D38026A7ECBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5B828500-C591-4B35-AFB2-D38026A7ECBC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8D44F07F-A1F8-4544-8EEF-B2FD99D0FBA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8D44F07F-A1F8-4544-8EEF-B2FD99D0FBA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8D44F07F-A1F8-4544-8EEF-B2FD99D0FBA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8D44F07F-A1F8-4544-8EEF-B2FD99D0FBA2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
- $0.TextStylePolicy = $1
+ $0.TextStylePolicy = $6
$1.inheritsSet = null
$1.scope = text/x-csharp
$0.CSharpFormattingPolicy = $2
@@ -77,27 +83,20 @@ Global
$2.inheritsSet = Mono
$2.inheritsScope = text/x-csharp
$2.scope = text/x-csharp
- $0.TextStylePolicy = $3
$3.NoTabsAfterNonTabs = True
$3.EolMarker = Windows
$3.inheritsSet = VisualStudio
$3.inheritsScope = text/plain
$3.scope = text/plain
- $0.TextStylePolicy = $4
$4.inheritsSet = null
$4.scope = application/config+xml
- $0.XmlFormattingPolicy = $5
+ $0.XmlFormattingPolicy = $7
$5.inheritsSet = null
$5.scope = application/config+xml
- $0.TextStylePolicy = $6
$6.inheritsSet = null
$6.scope = application/xml
- $0.XmlFormattingPolicy = $7
$7.inheritsSet = Mono
$7.inheritsScope = application/xml
$7.scope = application/xml
EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
EndGlobal
diff --git a/SharpFileSystem/FileSystemPath.cs b/SharpFileSystem/FileSystemPath.cs
index d5aeb2c..4c189f1 100644
--- a/SharpFileSystem/FileSystemPath.cs
+++ b/SharpFileSystem/FileSystemPath.cs
@@ -139,7 +139,7 @@ public bool IsParentOf(FileSystemPath path)
[Pure]
public bool IsChildOf(FileSystemPath path)
{
- return path.IsParentOf(this);
+ return path.IsParentOf(this) || path.Equals(this);
}
[Pure]