Пример #1
0
            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!");
            }
Пример #2
0
        /// <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();
                }
            }
        }