private void WriteCompressionToFile(string filePath, CompressionMetaData metaData, out long fileSize, out bool isSuccess)
 {
     using var fileStream = _fileService.Create(filePath);
     fileStream.Seek(metaData.MetaDataSize, SeekOrigin.Begin);
     isSuccess = WriteBlocksToStream(fileStream, metaData.BlockSizes.Length);
     _metaDataService.WriteToStream(fileStream, metaData);
     fileSize = fileStream.Length;
 }
 public void WriteToStream(Stream stream, CompressionMetaData metaData)
 {
     stream.Seek(0, SeekOrigin.Begin);
     using var binaryWriter = new BinaryWriter(stream, Encoding.UTF8, true);
     binaryWriter.Write(metaData.BlockSizes.Length);
     foreach (var blockSize in metaData.BlockSizes)
     {
         binaryWriter.Write(blockSize);
     }
 }
        public CompressionMetaData ReadFromStream(Stream stream)
        {
            using var binaryReader = new BinaryReader(stream, Encoding.UTF8, true);
            CheckBytesExist(stream, 4);
            var metaData = new CompressionMetaData(binaryReader.ReadInt32());

            CheckBytesExist(stream, (long)4 * metaData.BlockSizes.Length);
            for (int i = 0; i < metaData.BlockSizes.Length; i++)
            {
                var value = binaryReader.ReadInt32();
                if (value < 1)
                {
                    throw new InvalidDataException(CompressionExceptionMessages.WrongFormat);
                }
                metaData.BlockSizes[i] = value;
            }

            return(metaData);
        }
        public CompressionResult Compress(string inputFilePath, string outputFilePath)
        {
            using var inputFileStream = _fileService.OpenRead(inputFilePath);

            var blockCount = Math.Ceiling((double)inputFileStream.Length / BlockSize);

            if (blockCount > MaxBlockSize)
            {
                throw new InvalidDataException(CompressionExceptionMessages.TooManyBlocks);
            }

            var metaData = new CompressionMetaData((int)blockCount);

            long outputFileSize = 0;
            bool isSuccess      = false;
            var  writerThread   =
                _threadPool.RunDedicated(() => WriteCompressionToFile(outputFilePath, metaData, out outputFileSize, out isSuccess));

            for (int i = 0; i < metaData.BlockSizes.Length; i++)
            {
                var blockIndex = i;
                var blockBytes = ReadBlockFromStream(inputFileStream, BlockSize);
                _threadPool.Run(() =>
                                ProcessBlock(blockBytes, blockIndex, _compressService.Compress, metaData.BlockSizes));
            }

            writerThread.Join();

            if (!isSuccess)
            {
                throw new InvalidDataException(CompressionExceptionMessages.UnknownCompressException);
            }

            return(new CompressionResult(inputFileStream.Length, outputFileSize)
            {
                MetaData = metaData
            });
        }
 private void WriteDecompressionToFile(string filePath, CompressionMetaData metaData, out long fileSize, out bool isSuccess)
 {
     using var fileStream = _fileService.Create(filePath);
     isSuccess            = WriteBlocksToStream(fileStream, metaData.BlockSizes.Length);
     fileSize             = fileStream.Length;
 }