public static IObservable <string> ReadLineAsync(this Stream stream, Encoding encoding, int chunkSize = 65536) { return(ObservableForCompatible.Create <string>(observer => { var decoder = encoding.GetDecoder(); var bom = encoding.GetChars(encoding.GetPreamble()).FirstOrDefault(); var sb = new StringBuilder(); var prev = default(char); return stream.ReadAsync(chunkSize) .SelectMany(bytes => { var charBuffer = new char[encoding.GetMaxCharCount(bytes.Length)]; var count = decoder.GetChars(bytes, 0, bytes.Length, charBuffer, 0); return charBuffer.Take(count); }) .Subscribe( c => { if (c == bom) { } // skip bom else if (prev == '\r' && c == '\n') { } // when \r\n do nothing else if (c == '\r' || c == '\n') // reach at EndOfLine { var str = sb.ToString(); sb.Length = 0; observer.OnNext(str); } else { sb.Append(c); // normally char } prev = c; }, observer.OnError, () => { var str = sb.ToString(); if (str != "") { observer.OnNext(str); } observer.OnCompleted(); }); })); }
public static IObservable <Stream> GetRequestStreamAsObservable(this WebRequest request) { return(ObservableForCompatible.Create <Stream>(observer => { var disposable = new BooleanDisposable(); Observable.FromAsyncPattern <Stream>(request.BeginGetRequestStream, ar => { var res = request.EndGetRequestStream(ar); if (disposable.IsDisposed) { res.Close(); } return res; })().Subscribe(observer); return disposable; })); }