private void TransferChunks()

in AdlsDotNetSDK/FileTransfer/Jobs/CopyFileJob.cs [183:261]


        private void TransferChunks(Stream readStream, Stream writeStream)
        {
            readStream.Seek(_offset, SeekOrigin.Begin);
            var readBytes = new byte[BuffSize];
            // Index till which there is data already in the buffer
            var residualDataSize = 0;

            // Only for upload, non-binary and chunked uploads
            // Each thread respnsible for a chunk will look for the first newline in it's chunk and it will start uploading after that
            // And after it's chunk is uploaded then read forward into the next chunk till it gets a new line.
            if (Metadata.IsUpload && !Metadata.IsBinary && ChunkIndex > 0)
            {

                int indexAfterNewLine = ReadForwardTillNewLine(readStream, readBytes, 0);
                int finalReadData = (int)(readStream.Position - _offset); // Bytes of data read for getting a new line
                // If no new line found and the remaining data in stream was less than 4 MB then indexAfterNewLine is 0
                residualDataSize = finalReadData - indexAfterNewLine;
                if (residualDataSize > 0)
                {
                    Buffer.BlockCopy(readBytes, indexAfterNewLine , readBytes, 0, residualDataSize);
                }
            }

            if (!Metadata.IsUpload)
            {
                writeStream.Seek(_offset, SeekOrigin.Begin);
            }
            // if we have done readForwardTilNewLine then less data needs to be read now so update the lengthToRead
            long lengthToRead = _lengthToRead - (readStream.Position - _offset);
            while (lengthToRead > 0)
            {
                // Since we have data till residualDataSize in buffer we have to read remaining data in buffer
                int bufferDataSize = residualDataSize + ReadDataIntoBuffer(readStream, readBytes, residualDataSize, (int)Math.Min(BuffSize - residualDataSize, lengthToRead));
                if (bufferDataSize == residualDataSize)
                { // This will never be the case unless the file is being edited because if there was no data it would have been caught by lengthToRead>0
                    break;
                }

                int indexAfterlastNewLine = bufferDataSize;
                if (Metadata.IsUpload && !Metadata.IsBinary)
                {
                    indexAfterlastNewLine = GetNewLine(readBytes, 0, bufferDataSize, Metadata.EncodeType, true) + 1;
                }
                // For non binary uploads: indexAfterNewLine will be either the index after new line or 0 if no new line is found and data in the buffer is less than 4 MB
                // Rest scenarios: indexAfterNewLine will be buffer data length 
                if (indexAfterlastNewLine != 0)
                {
                    writeStream.Write(readBytes, 0, indexAfterlastNewLine);
                }
                else if (bufferDataSize == AdlsOutputStream.BufferMaxCapacity) // No newlines were found in 4MB
                {
                    throw new AdlsException($"No new lines obtained in {AdlsOutputStream.BufferMaxCapacity} of data at offset {readStream.Position - AdlsOutputStream.BufferMaxCapacity} for file {Metadata.SrcFile}. File should be uploaded as binary.");
                }
                // Length read this turn would be total buffer size minus the residual Data size, update the lengthToRead for next turn
                lengthToRead -= bufferDataSize - residualDataSize;
                // Compute new residualDataSize: data starting from indexAfterNewLine till total buffer size
                residualDataSize = bufferDataSize - indexAfterlastNewLine;
                // Move residual data to the start of the array.
                if (residualDataSize > 0)
                {
                    Buffer.BlockCopy(readBytes, indexAfterlastNewLine, readBytes, 0, residualDataSize);
                }
            }
            // Only for upload, non-binary and chunked uploads
            // Read forward into next chunk till it gets a new line
            if (Metadata.IsUpload && !Metadata.IsBinary && ChunkIndex >= 0 && ChunkIndex < Metadata.TotalChunks)
            {
                int indexAfterNewLine = ReadForwardTillNewLine(readStream, readBytes, residualDataSize);
                if (indexAfterNewLine != 0)
                {
                    residualDataSize = indexAfterNewLine;
                }
            }
            // For non binary uploads there can be residual data
            if (residualDataSize > 0)
            {
                writeStream.Write(readBytes, 0, residualDataSize);
            }
        }