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); }
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); }