PageRenderTime 8ms CodeModel.GetById 1ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/Source Code/FileArchive/ArchiveFile.vb

#
Visual Basic | 119 lines | 63 code | 26 blank | 30 comment | 1 complexity | ddad055ede50eb50e99d3e1c94fbd637 MD5 | raw file
  1Imports System.IO
  2
  3''' <summary>
  4''' Represents a file in an archive.
  5''' </summary>
  6Public Class ArchiveFile
  7
  8    Private FFileName As String = String.Empty
  9    Private FFile As BinaryReader = Nothing
 10    Private FFileTable As FileTable = Nothing
 11
 12    ''' <summary>
 13    ''' Do not allow construction of the <see cref="ArchiveFile" /> class.
 14    ''' </summary>
 15    ''' <param name="fileName">Name of the file.</param>
 16    Private Sub New(ByVal fileName As String)
 17        FFileName = fileName
 18        FFile = New BinaryReader(New FileStream(fileName, FileMode.Open))
 19        FFileTable = GetFileTable()
 20    End Sub
 21
 22    ''' <summary>
 23    ''' Closes the open archive file.
 24    ''' </summary>
 25    Public Sub Close()
 26        FFile.Close()
 27    End Sub
 28
 29    ''' <summary>
 30    ''' Creates a new archive file based on the specified file name and file table.
 31    ''' </summary>
 32    ''' <param name="fileName">Name of the file.</param>
 33    ''' <param name="fileTable">The file table that specifies what goes into the archive.</param>
 34    Public Shared Sub Create(ByVal fileName As String, ByVal fileTable As FileTable)
 35
 36        Dim File As New BinaryWriter(New FileStream(fileName, FileMode.Create))
 37
 38        ' Write file table
 39        WriteFileTable(File, fileTable)
 40
 41        ' Write the files
 42        For FileIndex As Integer = 0 To fileTable.FileCount - 1
 43            Dim TableEntry As EntryData = fileTable.Files(FileIndex)
 44            Dim InputFile As New BinaryReader(New FileStream(TableEntry.FileName, FileMode.Open))
 45            Dim FileLength As Integer = CInt(InputFile.BaseStream.Length)
 46            Dim Contents As Byte() = InputFile.ReadBytes(FileLength)
 47            fileTable.SetFilePosition(TableEntry.VirtualFileName, CInt(File.BaseStream.Position))
 48            File.Write(FileLength)
 49            File.Write(Contents)
 50            InputFile.Close()
 51        Next
 52
 53        ' Write the amended file table and close the file
 54        WriteFileTable(File, fileTable)
 55        File.Close()
 56
 57    End Sub
 58
 59    ''' <summary>
 60    ''' Loads the specified file.
 61    ''' </summary>
 62    ''' <param name="fileName">Name of the file to load.</param>
 63    ''' <returns>The archive file at the given location.</returns>
 64    Public Shared Function Load(ByVal fileName As String) As ArchiveFile
 65        Return New ArchiveFile(fileName)
 66    End Function
 67
 68    Public Function GetFile(ByVal virtualFileName As String) As Byte()
 69
 70        FFile.BaseStream.Position = FFileTable.GetFilePosition(virtualFileName)
 71        Dim FileLength As Integer = FFile.ReadInt32
 72        Return FFile.ReadBytes(FileLength)
 73
 74    End Function
 75
 76    ''' <summary>
 77    ''' Gets all files in the archive.
 78    ''' </summary>
 79    ''' <returns>A list of all of the files in the archive.</returns>
 80    Public Function GetAllFiles() As String()
 81        Return FFileTable.VirtualFileNames
 82    End Function
 83
 84    Private Function GetFileTable() As FileTable
 85
 86        FFile.BaseStream.Position = 0
 87        Dim FileCount As Integer = FFile.ReadInt32
 88        Dim Result As New FileTable
 89        For FileIndex As Integer = 0 To FileCount - 1
 90
 91            ' Get data about the file
 92            Dim VirtualFileName As String = FFile.ReadString
 93            Dim Position As Integer = FFile.ReadInt32
 94
 95            ' Do some sanity checking
 96            If VirtualFileName.Trim.Length = 0 Then Throw New ApplicationException("Virtual file name has not been specified.")
 97            If Position = 0 Then Throw New ApplicationException("Invalid position for file '" + VirtualFileName + "' in archive.")
 98
 99            ' Add the file to the list
100            Result.AddFile(VirtualFileName, VirtualFileName, Position)
101
102        Next
103        Return Result
104
105    End Function
106
107    Private Shared Sub WriteFileTable(ByVal file As BinaryWriter, ByVal fileTable As FileTable)
108
109        file.BaseStream.Position = 0
110        file.Write(fileTable.FileCount)
111        For FileIndex As Integer = 0 To fileTable.FileCount - 1
112            Dim TableEntry As EntryData = fileTable.Files(FileIndex)
113            file.Write(TableEntry.VirtualFileName)
114            file.Write(TableEntry.Position)
115        Next
116
117    End Sub
118
119End Class