public void StartRead() { bool canRead = true; int chunkNumber = 1; while (canRead) { bool canSend = false; lock (readLock) { if (readQueue.Count < queueCapacity) { canSend = true; } } if (canSend) { byte[] NextSlice = null; bool last = false; switch (CompressionType) { //For compression we can read const size of chunks case Compression.Enums.CompressionType.Compress: NextSlice = readProvider.ReadNext(out last); break; //For decompression we need to read specific chunks of byte, //so we detect how to read them by header specification case Compression.Enums.CompressionType.Decompress: NextSlice = readProvider .SpecificRead(Compression.Utils.MagicNumbersAlgorithmDictionary .AlgorithmMagicNumbers[algorithms].completeMask, out last); break; } //send data lock (readLock) { readQueue.Enqueue(new ByteBlock(NextSlice, chunkNumber, last)); } chunkNumber++; if (last) { canRead = false; } } else { Thread.Sleep(1); } } Console.WriteLine("[Output]: Data read completed!"); }
/// <summary> /// Main process /// </summary> /// <remarks> /// Using this method for milti threading file computation /// </remarks> /// <param name="param">Compression clone</param> private void Processing(object param) { //Each thread get his own compression copy of class Compression.Strategy.Compression compression = (Compression.Strategy.Compression)param; Compression.Enums.CompressionType type; bool last = false; lock (comptypeLock) { type = _compressionType; } while (!last) { lock (lastLock) { last = _last; } byte[] byteBlock = null; int current = GetCurrentBlock(); bool latest = false; lock (readLock) { switch (type) { //Read Next chunk of datam, if this is a compress, so we can read const size of block case Compression.Enums.CompressionType.Compress: byteBlock = _input.ReadNext(out latest); break; //Then we are decompressing we don't know the size of the block, so we need to read from the file by specification of //headers for compression case Compression.Enums.CompressionType.Decompress: byteBlock = _input.SpecificRead( Compression.Utils.MagicNumbersAlgorithmDictionary .AlgorithmMagicNumbers[compression.algorithms].completeMask, out latest); break; } } ByteBlock block = new ByteBlock(byteBlock, current, latest); current++; lock (currentLock) { _currentBlock++; } lock (lastLock) { _last = latest; } //Call method to compress or decompress switch (type) { case Compression.Enums.CompressionType.Compress: block.Slice = compression.Compress(block.Slice); break; case Compression.Enums.CompressionType.Decompress: block.Slice = compression.Decompress(block.Slice); break; } //Writing next chunk to the destination lock (writeLock) { _output.WriteNext(block.Slice); } block.Slice = null; //if the last block - call the handler if (latest) { waitHandle.Set(); } } }