Exemplo n.º 1
0
        private async Task <ReadData> ReadBufferInternal(byte[] managedBuffer)
        {
            ReadData readData;

            if (bytesToRead == 0)
            {
                // we knew on open that there was nothing to read
                readData.nRead = 0;
                readData.eof   = true;
                return(readData);
            }

            int toRead = (int)Math.Min((long)managedBuffer.Length, bytesToRead);

            Log.LogInformation("About to read buffer length " + toRead);
            readData.nRead = await AzureUtils.WrapInRetry(new PeloponneseLogger(Log.Logger), async() =>
            {
                return(await readStream.ReadAsync(managedBuffer, 0, toRead));
            });

            if (bytesToRead == Int64.MaxValue)
            {
                readData.eof = (readData.nRead < toRead);
            }
            else
            {
                if (readData.nRead == 0)
                {
                    throw new ApplicationException("Reader " + source.AbsoluteUri + " ran out of data with " + bytesToRead + " bytes remaining to read");
                }

                bytesToRead -= readData.nRead;
                readData.eof = (bytesToRead == 0);
            }

            Log.LogInformation("Read buffer length " + toRead + " got " + readData.nRead + " eof " + readData.eof);

            return(readData);
        }
Exemplo n.º 2
0
        private async Task <long> SeekStartOfLine(long currentOffset, long startOfNextBlock)
        {
            byte[] buffer = new byte[4 * 1024];

            readStream.Seek(currentOffset, SeekOrigin.Begin);

            long endOffset;

            if (startOfNextBlock == Int64.MaxValue)
            {
                endOffset = Int64.MaxValue;
            }
            else
            {
                // we may need to look as far as the first character in the next block
                endOffset = startOfNextBlock + 1;
            }

            bool foundReturn = false;

            while (currentOffset < endOffset)
            {
                int toRead = (int)Math.Min(buffer.LongLength, endOffset - currentOffset);

                int nRead = await AzureUtils.WrapInRetry(new PeloponneseLogger(Log.Logger), async() =>
                {
                    return(await readStream.ReadAsync(buffer, 0, toRead));
                });

                if (nRead == 0)
                {
                    // we hit end of stream
                    return(currentOffset);
                }

                for (int i = 0; i < nRead; ++i)
                {
                    if (buffer[i] == '\n')
                    {
                        // the next character is the first character of a line
                        return(currentOffset + i + 1);
                    }
                    else if (foundReturn)
                    {
                        // there was a '\r' that wasn't followed by a '\n', i.e. this is
                        // the first character of a line
                        return(currentOffset + i);
                    }
                    else if (buffer[i] == '\r')
                    {
                        // just flag this for now; if the next character is '\n' the next line
                        // starts after that, otherwise the next line starts with the next character
                        foundReturn = true;
                    }
                }

                currentOffset += nRead;
            }

            // the next line starts at some character >= startOfNextBlock+1, so it's not our problem
            return(currentOffset);
        }