using System; using System.Collections.Generic; using System.IO; using System.Linq.Expressions; using System.Text; namespace CPF.Windows.Json { internal static class StreamOperate { internal static Func GetStreamReaderCharBuffer = BuildStreamReaderCharBufferFunc(); internal static Func GetStreamReaderCharLen = BuildStreamReaderCharLenFunc(); static Func BuildStreamReaderCharBufferFunc() { var instance = Expression.Parameter(typeof(StreamReader)); var info = typeof(StreamReader).GetField("_charBuffer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamReader).GetField("charBuffer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var buf = Expression.MakeMemberAccess(instance, info); return Expression.Lambda>(buf, new[] { instance }).Compile(); } static Func BuildStreamReaderCharLenFunc() { var instance = Expression.Parameter(typeof(StreamReader)); var info = typeof(StreamReader).GetField("_charLen", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamReader).GetField("charLen", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var len = Expression.MakeMemberAccess(instance, info); return Expression.Lambda>(len, new[] { instance }).Compile(); } internal static Func GetStreamWriterCharBuffer = BuildStreamWriterCharBufferFunc(); internal static Func GetStreamWriterCharLen = BuildStreamWriterCharPosFunc(); internal static Action SetStreamWriterCharLen = BuildSetStreamWriterCharPosFunc(); static Func BuildStreamWriterCharBufferFunc() { var instance = Expression.Parameter(typeof(StreamWriter)); var info = typeof(StreamWriter).GetField("_charBuffer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamWriter).GetField("charBuffer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var buf = Expression.MakeMemberAccess(instance, info); return Expression.Lambda>(buf, new[] { instance }).Compile(); } static Func BuildStreamWriterCharPosFunc() { var instance = Expression.Parameter(typeof(StreamWriter)); var info = typeof(StreamWriter).GetField("_charPos", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamWriter).GetField("charPos", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var pos = Expression.MakeMemberAccess(instance, info); return Expression.Lambda>(pos, new[] { instance }).Compile(); } static Action BuildSetStreamWriterCharPosFunc() { var instance = Expression.Parameter(typeof(StreamWriter)); var num = Expression.Parameter(typeof(int)); var info = typeof(StreamWriter).GetField("_charPos", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamWriter).GetField("charPos", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var pos = Expression.MakeMemberAccess(instance, info); var assign = Expression.Assign(pos, num); return Expression.Lambda>(assign, new[] { instance, num }).Compile(); } internal unsafe static void Remove(this StreamWriter streamWriter, int start, int length) { int pos = GetStreamWriterCharLen(streamWriter); SetStreamWriterCharLen(streamWriter, pos - length); if (start + length == pos) return; char[] buf = GetStreamWriterCharBuffer(streamWriter); Array.Copy(buf, start + length, buf, start, pos - (start + length)); } } }