public IObservable<DataBlock> ReadBlocksFromFile(string filename) { var obs = Observable.Create<DataBlock>(async (subject, token) => { try { using (var stream = File.Open(filename, FileMode.Open, FileAccess.Read)) { using (var reader = new StreamReader(stream)) { DataBlock prev = null; while (!reader.EndOfStream) { if (token.IsCancellationRequested) break; var block = new DataBlock(BufferSize); block.PreviousBlock = prev; block = await ReadBlockAsync(reader, block); subject.OnNext(block); prev = block; } subject.OnCompleted(); } } } catch (Exception ex) { subject.OnError(ex); } }); return obs; }
private async Task<DataBlock> ReadBlockAsync(StreamReader reader, DataBlock target) { var readBytes = await reader.ReadAsync(target.Data, 0, BufferSize); if (readBytes != BufferSize) { target.ResizeData(readBytes); } return target; }
public IEnumerable<DataEntry> Refine(DataBlock source) { if (_lastEol == null) { _lastEol = new EndOfLine(source); _lastEol.RelativePosition = 0; } foreach(var eol in FindLineEnds(source)) { yield return Build(eol); _lastEol = eol; } }
private List<DataBlock> FindLast(DataBlock start) { var p = start; var buffer = new Stack<DataBlock>(); while(p != _lastEol.Block) { buffer.Push(p); if (p.PreviousBlock == null) { return buffer.ToList(); } p = p.PreviousBlock; } buffer.Push(p); return buffer.ToList(); }
private IEnumerable<EndOfLine> FindLineEnds(DataBlock block) { var currentResult = new EndOfLine(block); for(int currentPos = 0; currentPos < block.Length; currentPos++) { if (block.Data[currentPos] == EndOfLine.LineFeed) { currentResult.RelativePosition = currentPos; yield return currentResult; currentResult = new EndOfLine(block); } if (block.Data[currentPos] == EndOfLine.CarriageReturn) { currentResult.IsWindowsEndOfLine = true; } } yield break; }
public EndOfLine(DataBlock b) { Block = b; RelativePosition = Unknown; IsWindowsEndOfLine = false; }