public void TestTwoTitles() { var input = new byte[] { 31, 139, 8, 0, 0, 0, 0, 0, 4, 0, 1, 31, 139, 8, 0, 0, 0, 0, 0, 4, 0 }; var buffer = new BytesBuffer(input, 0, input.Length - 1); var portion = new ArhivePortion(buffer); var firstExtracted = portion.ExtractFirstTitleAndData(); Assert.IsNotNull(firstExtracted, "firstExtracted == null"); Assert.AreEqual(0, firstExtracted.StartPosition, "firstExtracted.StartPosition"); Assert.AreEqual(10, firstExtracted.EndPosition, "firstExtracted.EndPosition"); Assert.AreEqual(11, firstExtracted.Size, "firstExtracted.Size"); Assert.IsFalse(portion.IsEmpty, "portion.IsEmpty"); Assert.IsTrue(portion.IsExistsTitle, "portion.IsExistsTitle"); var secondExtracted = portion.ExtractFirstTitleAndData(); Assert.IsNotNull(secondExtracted, "secondExtracted == null"); Assert.AreEqual(11, secondExtracted.StartPosition, "secondExtracted.StartPosition"); Assert.AreEqual(20, secondExtracted.EndPosition, "secondExtracted.EndPosition"); Assert.AreEqual(10, secondExtracted.Size, "secondExtracted.Size"); Assert.IsTrue(portion.IsEmpty, "portion.IsEmpty"); Assert.IsFalse(portion.IsExistsTitle, "portion.IsExistsTitle"); }
public void DataBeforePartTitle() { var input = new byte[] { 1, 31, 139, 8, 0, 0, 0 }; var buffer = new BytesBuffer(input, 0, input.Length - 1); var portion = new ArhivePortion(buffer); var extracted = portion.ExtractDataBeforeTitle(); Assert.IsNotNull(extracted, "extracted == null"); Assert.AreEqual(0, extracted.StartPosition, "extracted.StartPosition"); Assert.AreEqual(0, extracted.EndPosition, "extracted.EndPosition"); Assert.AreEqual(1, extracted.Size, "extracted.Size"); Assert.IsTrue(portion.IsNotEmpty, "portion.IsNotEmpty"); Assert.IsTrue(portion.IsExistsTitle, "portion.IsExistsTitle"); }
public void TestAppendPartTitle() { var first = new byte[] { 31, 139, 8, 0, 0 }; var firstBuffer = new BytesBuffer(first, 0, first.Length - 1); var portion = new ArhivePortion(firstBuffer); var second = new byte[] { 0, 0, 0, 4, 0, 1 }; var secondBuffer = new BytesBuffer(second, 0, second.Length - 1); portion.Append(secondBuffer); Assert.IsTrue(portion.IsExistsAllTitle, "порция должна содержать title"); var titleAndData = portion.ExtractFirstTitleAndData(); Assert.AreEqual(0, titleAndData.StartPosition, "titleAndData.StartPosition"); Assert.AreEqual(11, titleAndData.Size, "titleAndData.StartPosition"); Assert.IsTrue(titleAndData.InnerBuffer.SequenceEqual(new byte[] { 31, 139, 8, 0, 0, 0, 0, 0, 4, 0, 1 }), "неверный titleAndData"); }
public override bool ReadPart(FilePart part) { // одна часть архива - она полностью пойдет на декомпрессию var archivePart = new ArchivePart(); ArhivePortion arhivePortion = null; while (archivePart != null) { if (_portionFromPrev != null) { // используем порцию оставщуюся с предыдущей части arhivePortion = _portionFromPrev; _portionFromPrev = null; } else { // читаем порцию из файла var buffer = new byte[BufferSize]; var count = SourceStream.Read(buffer, 0, buffer.Length); if (count > 0) { _totalReadByte = _totalReadByte + count; if (arhivePortion == null) { arhivePortion = new ArhivePortion(new BytesBuffer(buffer, 0, count - 1)); } else { // предыдущая порция закончилась на части заголовка arhivePortion.Append(new BytesBuffer(buffer, 0, count - 1)); } } else { // всё в part part.Source = archivePart.ToArray(); part.IsLast = true; Logger.Add($"Поток {Thread.CurrentThread.Name} прочитал последнюю часть файла {part} "); return(true); } } // нашли заголовок if (arhivePortion.IsExistsTitle) { // нашли заголовок полностью if (arhivePortion.IsExistsAllTitle) { // заголовок в начале if (arhivePortion.StartsWithTitle) { // часть архива пустая - нашли заголовок для текущей части if (archivePart.IsEmpty) { // записываем в часть все что до следующего заголовка archivePart.AppendTitleAndDataBeforeNextTitle(arhivePortion); if (arhivePortion.IsNotEmpty) { // если остаток порции не пустой, то возможно начался новый заголовок // в остатке есть заголовок полностью if (arhivePortion.IsExistsAllTitle) { // всё в part part.Source = archivePart.ToArray(); // а остаток нужно "припасти" для следующей part _portionFromPrev = arhivePortion; return(true); } // в остатке есть заголовок, но не полностью // !!! окончить текущую часть не имеем права - не удостоверившись, что это заголовок // поэтому здесь ничего не делаем // ... и далее на чтение следующей порции } else { arhivePortion = null; // ... и дальше на чтение следующей порции } } else { // нашли заголовок для следующей части - значит текущая часть сформирована, а все что осталось в порции уже для следующей части // порцию нужно "припасти" для следующей part _portionFromPrev = arhivePortion; // всё в part part.Source = archivePart.ToArray(); return(true); } } else { // заголовок не в начале порции if (archivePart.IsEmpty) { throw new FormatException( $"part {part}. archivePart ещё пустая, а в порции заголовок не в начале - неверный формат архива"); } // добавляем в часть всё что до заголовка archivePart.AppendDataBeforeTitle(arhivePortion); // всё в part part.Source = archivePart.ToArray(); // порцию нужно "припасти" для следующей part _portionFromPrev = arhivePortion; return(true); } } else { // нашли заголовок не полностью // !!! окончить текущую часть не имеем права - не удостоверившись, что это заголовок // поэтому здесь ничего не делаем // ... и далее на чтение следующей порции } } else { // заголовок не нашли в порции if (archivePart.IsEmpty) { throw new FormatException("Часть ещё пустая, а в порции нет заголовка - неверный формат архива"); } // всю прочитанную порцию архива в часть archivePart.AppendAllPortion(arhivePortion); Debug.Assert(arhivePortion.IsEmpty, "Всё извлекли из порции, а она всё равно не пустая"); arhivePortion = null; // ... и далее на чтение следующей порции } } throw new Exception("Обнаружена неправильная работа ArсhivePartReader"); }
public void TestOneByte() { var portion = new ArhivePortion(new BytesBuffer(new byte[] { 1 }, 0, 0)); Assert.IsFalse(portion.IsEmpty, "IsNotEmpty"); }