public void Md5Hash_GetHash_Null_3() { IHash hashAlgo = new Md5Hash(); Action action = () => hashAlgo.GetHash(null as FileInfo); action.Should().Throw <ArgumentNullException>(); }
public void Md5Hash_GetHash_Empty() { IHash hashAlgo = new Md5Hash(); Action action = () => hashAlgo.GetHash(string.Empty); action.Should().Throw <ArgumentNullException>(); }
public void Md5Hash_GetHash_Valid_2() { IHash hashAlgo = new Md5Hash(); HashResult hashResult = hashAlgo.GetHash(Data.ExpectedHashFilePath); hashResult.Algorithm.Should().Be(Hashing.ExpectedMd5Algorithm); hashResult.Value.Should().Be(Hashing.ExpectedMd5Hash); }
public void Md5Hash_GetHash_Valid_1() { IHash hashAlgo = new Md5Hash(); using FileStream fileStream = new(Data.ExpectedHashFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); HashResult hashResult = hashAlgo.GetHash(fileStream); hashResult.Algorithm.Should().Be(Hashing.ExpectedMd5Algorithm); hashResult.Value.Should().Be(Hashing.ExpectedMd5Hash); }
/// <summary> /// /// </summary> /// <param name="fileToWrite"></param> /// <param name="token"></param> public void Write(EdataFile edataFile, CancellationToken token) { //Uważać tu na ścieżke jaka ma edata pełną czy relatywną.. //No i dodatkowo od tego momentu może być pusta. A z racji tego że tylko możemy podmieniać edata nie pasuje //dodawać dodatkowy argument ścieżki do zapisu, bo to jasno wskazywało by że możemy zapisywać do dowolnej lokacji // a tak naprawde można tylko podmieniać edata. if (!File.Exists(edataFile.Path)) { throw new ArgumentException( String.Format("A following Edata file: \"{0}\" doesn't exist", edataFile.Path), "edataFile"); } //Cancel if requested; token.ThrowIfCancellationRequested(); var edataContentFiles = edataFile.ContentFiles.OfType <EdataContentFile>(); //Wypieprzyć z tąd wszystkie zależności od starych metod, i stworzyć nowe metody zapisu poszczegołnych elementów //realizujące nową koncepcję wykorzystujaca model wpsiów słownika i być może w przyszłosci samego słownika. //W przypadku konieczności odbudowy słownika trzeba poszerzyć określenie czy można użyć ReplacemnetWrite //Jeśli nie ma nowego pliku, i słownik mieści sie w miejsce starego, to można użyć replacement write //Jeśli natomiast dodano nowy plik, lub słownik nie miesci sie na miejsce starego to trzeba zbudować plik Edata od zera. //Update na dobrą sprawę można założyć, że jeśli nie ma zmian w plikach to słownik zawszę będzie się mieścił w miejsce starego. if (!AnyContentFileExceedsAvailableSpace(edataFile) && !edataFile.HasContentFilesCollectionChanged) { using (var sourceEdata = new FileStream(edataFile.Path, FileMode.Open)) { //Taka uwaga: Nie robić canceli w trakcie zapisu czy to nagłowka czy słownika, zeby w przypadku przerwania bez backapu zminimalizwoać // szanse na uszkodzenie modyifkowane go pliku. //W tym przypadku używamy starego rozmieszczenia danych żeby nie odbudowywac pliku od nowa. var header = edataFile.Header; var dictRoot = CreateDictionaryEntries(edataContentFiles); uint dictOffset = header.DictOffset; uint dictLength = ComputeDictionaryLength(dictRoot); uint dictEnd = dictOffset + dictLength; WriteLoadedContentByReplace(sourceEdata, edataContentFiles, token); AssignContentFilesInfoToDictEntries(edataContentFiles, dictRoot); //Clear the old part of file up to content. WritePadding(sourceEdata, 0, header.FileOffset); var dictWriteInfo = WriteDictionary(sourceEdata, dictRoot, dictOffset); header.Checksum_V2 = Md5Hash.GetHash(dictWriteInfo.Checksum); header.DictLength = dictWriteInfo.Length; WriteHeader(sourceEdata, header, 0); } } else { //Try in the current dir to avoid double file moving String temporaryEdataPath = PathUtilities.GetTemporaryPath(edataFile.Path); if ((new FileInfo(edataFile.Path).Length > (new DriveInfo(temporaryEdataPath).AvailableFreeSpace))) { temporaryEdataPath = TryGetTemporaryEdataPathWhereFree(edataFile.Path); if (temporaryEdataPath == null) { throw new IOException( String.Format("Not enough free disk space for rebuilding the \"{0}\" file.", edataFile.Path)); } } //To avoid too many nested try catches. FileStream sourceEdata = null; FileStream newEdata = null; try { sourceEdata = new FileStream(edataFile.Path, FileMode.Open); newEdata = new FileStream(temporaryEdataPath, FileMode.Create); //W tym przypadku rozmieszczamy wszystko od zera wg wartości obliczonych. var dictRoot = CreateDictionaryEntries(edataContentFiles); uint dictOffset = GetDictionaryOffset(); uint dictLength = ComputeDictionaryLength(dictRoot); uint dictEnd = dictOffset + dictLength; uint fileOffset = GetFileOffset(dictEnd); var contentWriteInfo = WriteNotLoadedContent(sourceEdata, newEdata, edataContentFiles, fileOffset, token); AssignContentFilesInfoToDictEntries(edataContentFiles, dictRoot); WritePadding(newEdata, 0, fileOffset); var dictWriteInfo = WriteDictionary(newEdata, dictRoot, dictOffset); var header = edataFile.Header; header.Checksum_V2 = Md5Hash.GetHash(dictWriteInfo.Checksum); header.DictOffset = dictOffset; header.DictLength = dictWriteInfo.Length; header.FileOffset = fileOffset; header.FileLenght = contentWriteInfo.Length; WriteHeader(newEdata, header, 0); //Free file handles before the file move and delete CloseEdataFilesStreams(sourceEdata, newEdata); //Replace temporary file File.Delete(edataFile.Path); File.Move(temporaryEdataPath, edataFile.Path); } finally { //Spr czy zostały już zwolnione...? CloseEdataFilesStreams(sourceEdata, newEdata); if (File.Exists(temporaryEdataPath)) { File.Delete(temporaryEdataPath); } } } }
/// <summary> /// /// </summary> /// <param name="edataFile"></param> /// <param name="token"></param> /// <returns></returns> public virtual byte[] Write(EdataFile edataFile, CancellationToken token) { //Cancel if requested; token.ThrowIfCancellationRequested(); var edataContentFiles = edataFile.ContentFiles.OfType <EdataContentFile>(); using (MemoryStream edataStream = new MemoryStream()) { if (!AnyContentFileExceedsAvailableSpace(edataFile) && !edataFile.HasContentFilesCollectionChanged) { var header = edataFile.Header; var dictRoot = CreateDictionaryEntries(edataContentFiles); uint dictOffset = header.DictOffset; uint dictLength = ComputeDictionaryLength(dictRoot); uint dictEnd = dictOffset + dictLength; //Clear the old part of file up to content. WritePadding(edataStream, 0, header.FileOffset); WriteLoadedContentByReplace(edataStream, edataContentFiles, token); AssignContentFilesInfoToDictEntries(edataContentFiles, dictRoot); var dictWriteInfo = WriteDictionary(edataStream, dictRoot, dictOffset); header.Checksum_V2 = Md5Hash.GetHash(dictWriteInfo.Checksum); header.DictLength = dictWriteInfo.Length; WriteHeader(edataStream, header, 0); } else { //W tym przypadku rozmieszczamy wszystko od zera wg wartości obliczonych. var dictRoot = CreateDictionaryEntries(edataContentFiles); uint dictOffset = GetDictionaryOffset(); uint dictLength = ComputeDictionaryLength(dictRoot); uint dictEnd = dictOffset + dictLength; uint fileOffset = GetFileOffset(dictEnd); WritePadding(edataStream, 0, fileOffset); var contentWriteInfo = WriteLoadedContent(edataStream, edataContentFiles, fileOffset, token); AssignContentFilesInfoToDictEntries(edataContentFiles, dictRoot); var dictWriteInfo = WriteDictionary(edataStream, dictRoot, dictOffset); var header = edataFile.Header; header.Checksum_V2 = Md5Hash.GetHash(dictWriteInfo.Checksum); header.DictOffset = dictOffset; header.DictLength = dictWriteInfo.Length; header.FileOffset = fileOffset; header.FileLenght = contentWriteInfo.Length; WriteHeader(edataStream, header, 0); } return(edataStream.ToArray()); } }