Пример #1
0
        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");
        }
Пример #2
0
        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");
        }
Пример #3
0
        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");
        }
Пример #4
0
        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");
        }
Пример #5
0
        public void TestOneByte()
        {
            var portion = new ArhivePortion(new BytesBuffer(new byte[] { 1 }, 0, 0));

            Assert.IsFalse(portion.IsEmpty, "IsNotEmpty");
        }