/// <summary> /// Analyzes package at sent path /// </summary> /// <param name="packagePath">Path of analyzable package file</param> /// <returns><see cref="PackageMetadata"/> of package file</returns> /// <exception cref="InvalidFiletypeException"></exception> /// <exception cref="InvalidVersionException"></exception> /// <exception cref="IOException"></exception> public static PackageMetadata AnalyzePackage(string packagePath) { using (BinaryReader reader = new BinaryReader(File.OpenRead(packagePath))) { byte prehead = reader.ReadByte(); byte version = reader.ReadByte(); byte[] header = reader.ReadBytes(8); if (prehead == prehd && ByteArrayValidator.ValidateBytes(head, header)) { switch (version) { case PackageVersions.Version1: string packageNameString = reader.ReadString(); DateTime packageCreationTime = DateTime.FromBinary(reader.ReadInt64()); int filesTotal = reader.ReadInt32(); byte[] sep = new byte[] { 0x1f, 0x1f, 0xfd }; long _totalallBytes = 0; List <PackageFileWithoutData> _files = new List <PackageFileWithoutData>(); for (int i = 0; i < filesTotal; i++) { string filename = reader.ReadString(); long filesize = reader.ReadInt64(); _totalallBytes += filesize; _files.Add(new PackageFileWithoutData(filename, filesize)); } PackageMetadata _meta = new PackageMetadata(packageNameString, _files.ToArray(), packageCreationTime, version); return(_meta); case PackageVersions.Version2: string packageNameString1 = reader.ReadString(); DateTime packageCreationTime1 = DateTime.FromBinary(reader.ReadInt64()); int filesTotal1 = reader.ReadInt32(); byte[] sep1 = new byte[] { 0x1f, 0x1f, 0xfd }; long _totalallBytes1 = 0; List <PackageFileWithoutData> _files1 = new List <PackageFileWithoutData>(); for (int i = 0; i < filesTotal1; i++) { string filename = reader.ReadString(); long filesize = reader.ReadInt64(); _totalallBytes1 += filesize; _files1.Add(new PackageFileWithoutData(filename, filesize)); } PackageMetadata _meta1 = new PackageMetadata(packageNameString1, _files1.ToArray(), packageCreationTime1, version); return(_meta1); default: throw new InvalidVersionException(version); } } else { throw new InvalidFiletypeException(); } } }
/// <summary> /// Starts extraction /// </summary> /// <exception cref="InvalidFiletypeException"></exception> /// <exception cref="InvalidVersionException"></exception> /// <exception cref="PackageCorruptedException"></exception> /// <exception cref="IOException"></exception> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <exception cref="PathTooLongException"></exception> /// <exception cref="DirectoryNotFoundException"></exception> /// <exception cref="UnauthorizedAccessException"></exception> /// <exception cref="FileNotFoundException"></exception> /// <exception cref="NotSupportedException"></exception> /// <exception cref="System.Security.SecurityException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="ObjectDisposedException"></exception> /// <exception cref="EndOfStreamException"></exception> public void Extract() { ExtractingEventArgs _eea = new ExtractingEventArgs(); ExtractingDoneEventArgs _edea = new ExtractingDoneEventArgs() { IsSuccessful = false }; try { using (BinaryReader reader = new BinaryReader(File.OpenRead(PackagePath))) { _eea.CurrentFilename = "VALIDATION"; _eea.CurrentFileByte = 0; _eea.TotalAllBytes = 0; _eea.TotalFileByte = 0; ExtractingEvent?.Invoke(this, _eea); byte prehead = reader.ReadByte(); byte version = reader.ReadByte(); byte[] header = reader.ReadBytes(8); byte[] sep = new byte[] { 0x1f, 0x1f, 0xfd }; if (prehead == prehd && ByteArrayValidator.ValidateBytes(head, header)) { switch (version) { case PackageVersions.Version1: string packageNameString = reader.ReadString(); DateTime packageCreationTime = DateTime.FromBinary(reader.ReadInt64()); int filesTotal = reader.ReadInt32(); Dictionary <string, long> _filetable = new Dictionary <string, long>(); long _totalallBytes = 0; for (int i = 0; i < filesTotal; i++) { string filename = reader.ReadString(); long filesize = reader.ReadInt64(); _totalallBytes += filesize; _filetable.Add(filename, filesize); } _eea.TotalAllBytes = _totalallBytes; ExtractingEvent?.Invoke(this, _eea); if (!Directory.Exists(DirectoryForExtracted)) { Directory.CreateDirectory(DirectoryForExtracted); } if (ByteArrayValidator.ValidateBytes(reader.ReadBytes(3), sep)) { int currflctr = 0; foreach (var fileInTable in _filetable) { currflctr++; _eea.CurrentFilename = fileInTable.Key; _eea.TotalFileByte = fileInTable.Value; _eea.CurrentFileIndex = currflctr; ExtractingEvent?.Invoke(this, _eea); using (BinaryWriter writer = new BinaryWriter(File.Create(Path.Combine(DirectoryForExtracted, fileInTable.Key)))) { for (long curByte = 0; curByte < fileInTable.Value; curByte++) { _eea.CurrentFileByte = curByte; ExtractingEvent?.Invoke(this, _eea); writer.Write(reader.ReadByte()); } } } } else { throw new PackageCorruptedException(); } _edea.IsSuccessful = true; ExtractingDoneEvent?.Invoke(this, _edea); break; case PackageVersions.Version2: _eea.ExtractingPercentage = 0; long _totalBytesWithMeta = 0; string packageNameString2 = reader.ReadString(); DateTime packageCreationTime2 = DateTime.FromBinary(reader.ReadInt64()); int filesTotal2 = reader.ReadInt32(); Dictionary <string, long> _filetable2 = new Dictionary <string, long>(); long _totalallBytes2 = 0; for (int i = 0; i < filesTotal2; i++) { string filename = reader.ReadString(); long filesize = reader.ReadInt64(); _totalallBytes2 += filesize; _filetable2.Add(filename, filesize); } _totalBytesWithMeta = reader.BaseStream.Position + _totalallBytes2; _eea.TotalAllBytes = _totalallBytes2; ExtractingEvent?.Invoke(this, _eea); if (!Directory.Exists(DirectoryForExtracted)) { Directory.CreateDirectory(DirectoryForExtracted); } if (ByteArrayValidator.ValidateBytes(reader.ReadBytes(3), sep)) { int currflctr = 0; foreach (var fileInTable in _filetable2) { currflctr++; _eea.CurrentFilename = fileInTable.Key; _eea.TotalFileByte = fileInTable.Value; _eea.CurrentFileIndex = currflctr; ExtractingEvent?.Invoke(this, _eea); using (BinaryWriter writer = new BinaryWriter(File.Create(Path.Combine(DirectoryForExtracted, fileInTable.Key)))) { _eea.CurrentFilename = fileInTable.Key; _eea.TotalFileByte = fileInTable.Value; _eea.CurrentFileIndex = currflctr; writer.BaseStream.Write(reader.ReadBytes((int)fileInTable.Value), 0, (int)fileInTable.Value); _eea.ExtractingPercentage = (int)(((double)reader.BaseStream.Position / _totalBytesWithMeta) * 100.0d); ExtractingEvent?.Invoke(this, _eea); } } } else { throw new PackageCorruptedException(); } _edea.IsSuccessful = true; ExtractingDoneEvent?.Invoke(this, _edea); break; default: throw new InvalidVersionException(version); } } else { throw new InvalidFiletypeException(); } } } catch (Exception e) { _edea.InnerException = e; ExtractingDoneEvent?.Invoke(this, _edea); throw e; } }