Modules/Filesystem/FileContainer.vb
Jonathan Jenne 0073fee1f9 jj
2018-11-22 11:44:33 +01:00

204 lines
6.1 KiB
VB.net

Imports System.IO
Imports DigitalData.Modules.Logging
Imports ProtoBuf
''' <module>FileContainer</module>
''' <version>0.0.0.2</version>
''' <date>21.11.2018</date>
''' <summary>
''' File Container for securely saving files
''' </summary>
''' <dependencies>
''' NLog, >= 4.5.8
''' </dependencies>
''' <params>
''' LogConfig, DigitalData.Module.Logging.LogConfig
''' A LogConfig object
''' Password, String
''' The Password to Encrypt
''' Path, String
''' The Path to save/load the container
''' </params>
''' <example>
''' dim oContainer = Container.Create(logConfig, "pass", "E:\some.container")
''' dim oContainer = Container.Load(logConfig, "pass", "E:\some.container")
'''
''' dim oContainer = new Container(logConfig, "pass", "E:\some.container")
''' oContainer.Save()
'''
''' dim oContainer = new Container(logConfig, "pass", "E:\some.container")
''' oContainer.Contents = oSomeData
''' oContainer.Save()
'''
''' dim oContainer = new Container(logConfig, "pass", "E:\some.container")
''' oContainer.Load()
''' dim oContents = oContainer.Contents
'''
''' dim oContainer = new Container(logConfig, "pass", "E:\some.container")
''' oContainer.Load()
''' oContainer.Contents = oSomeOtherData
''' oContainer.Save()
''' oContainer.SaveAs("E:\some2.container")
''' </example>
Public Class FileContainer
Private _crypto As Encryption
Private _compression As Compression
Private _containerId As Guid
Private _inner As FileContainerInner
Private _logger As Logger
Private _logConfig As LogConfig
Private _path As String
Public Property Contents As Byte()
Get
Return _inner.Contents
End Get
Set(value As Byte())
_inner.Contents = value
End Set
End Property
Public Property Extension As String
Get
Return _inner.Extension
End Get
Set(value As String)
_inner.Extension = value
End Set
End Property
Public ReadOnly Property FileId As String
Get
Return _inner.FileId
End Get
End Property
Public ReadOnly Property CreatedAt As String
Get
Return _inner.CreatedAt
End Get
End Property
Public ReadOnly Property UpdatedAt As String
Get
Return _inner.UpdatedAt
End Get
End Property
Public Shared Function Create(LogConfig As LogConfig, Password As String) As FileContainer
Dim oContainer = New FileContainer(LogConfig, Password)
Return oContainer
End Function
Public Shared Function Load(LogConfig As LogConfig, Password As String, Path As String) As FileContainer
Dim oContainer = New FileContainer(LogConfig, Password, Path)
oContainer.Load()
Return oContainer
End Function
Public Sub New(LogConfig As LogConfig, Password As String, Path As String)
_logger = LogConfig.GetLogger()
_crypto = New Encryption(LogConfig, Password)
_compression = New Compression(LogConfig)
_inner = New FileContainerInner()
_path = Path
End Sub
Public Sub New(LogConfig As LogConfig, Password As String)
_logger = LogConfig.GetLogger()
_crypto = New Encryption(LogConfig, Password)
_compression = New Compression(LogConfig)
_inner = New FileContainerInner()
End Sub
Public Sub SetFile(Contents As Byte(), Extension As String)
_inner.Contents = Contents
_inner.Extension = Extension
End Sub
Public Function GetFile() As FileContainerInner
Return _inner
End Function
Public Sub Save()
If IsNothing(_path) Then
Throw New ArgumentException("Path not set")
End If
SaveAs(_path)
End Sub
Public Sub SaveAs(Path As String)
Try
WriteBytesToFile(TransformToBytes(_inner), Path)
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Sub
Public Sub Load()
If IsNothing(_path) Then
Throw New ArgumentException("Path not set")
End If
LoadFrom(_path)
End Sub
Public Sub LoadFrom(Path As String)
Try
_inner = TransformToObject(ReadBytesFromFile(_path))
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Sub
Private Function TransformToBytes([Object] As FileContainerInner) As Byte()
Dim oBytes = Serialize([Object])
Dim oCompressed = _compression.Compress(oBytes)
Dim oEncrypted = _crypto.Encrypt(oCompressed)
Return oEncrypted
End Function
Private Function TransformToObject(Bytes As Byte()) As FileContainerInner
Dim oDecrypted = _crypto.Decrypt(Bytes)
Dim oDecompressed = _compression.Decompress(oDecrypted)
Dim oObject = Deserialize(oDecompressed)
Return oObject
End Function
Private Function Serialize(InnerData As FileContainerInner) As Byte()
Dim oBinaryData As Byte()
Using oStream As New MemoryStream
Serializer.Serialize(oStream, InnerData)
oBinaryData = oStream.ToArray()
End Using
Return oBinaryData
End Function
Private Function Deserialize(InnerData As Byte()) As FileContainerInner
Dim oObject As FileContainerInner
Using oStream As New MemoryStream(InnerData)
oObject = Serializer.Deserialize(Of FileContainerInner)(oStream)
End Using
Return oObject
End Function
Private Sub WriteBytesToFile(Data As Byte(), FilePath As String)
Using oSourceStream As New FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
oSourceStream.Write(Data, 0, Data.Length)
oSourceStream.Flush()
End Using
End Sub
Private Function ReadBytesFromFile(FilePath As String) As Byte()
Using oFileStream = New FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096)
Dim oBuffer As Byte() = New Byte(oFileStream.Length - 1) {}
oFileStream.Read(oBuffer, 0, oFileStream.Length)
oFileStream.Close()
Return oBuffer
End Using
End Function
End Class