using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using NewLife.Collections;
namespace NewLife.Log
{
/// <summary>跟踪流。包装一个基础数据流,主要用于重写Read/Write等行为,跟踪程序操作数据流的过程</summary>
public class TraceStream : Stream
{
#region 属性
private Stream _BaseStream;
/// <summary>基础流</summary>
public Stream BaseStream
{
get { return _BaseStream; }
set { _BaseStream = value; }
}
private ICollection<String> _TraceMembers;
/// <summary>跟踪的成员</summary>
public ICollection<String> TraceMembers
{
get { return _TraceMembers ?? (_TraceMembers = new HashSet<String>(DefaultTraceMembers, StringComparer.OrdinalIgnoreCase)); }
set { _TraceMembers = value; }
}
private Boolean _IsLittleEndian = true;
/// <summary>是否小端字节序。x86系列则采用Little-Endian方式存储数据;网络协议都是Big-Endian;</summary>
/// <remarks>
/// 网络协议都是Big-Endian;
/// Java编译的都是Big-Endian;
/// Motorola的PowerPC是Big-Endian;
/// x86系列则采用Little-Endian方式存储数据;
/// ARM同时支持 big和little,实际应用中通常使用Little-Endian。
/// </remarks>
public Boolean IsLittleEndian { get { return _IsLittleEndian; } set { _IsLittleEndian = value; } }
static readonly String[] DefaultTraceMembers = new String[] { "Write", "WriteByte", "Read", "ReadByte", "BeginRead", "BeginWrite", "EndRead", "EndWrite", "Seek", "Close", "Flush", "SetLength", "SetPosition" };
private Int32 _ShowPositionStep = 10;
/// <summary>显示位置的步长,位移超过此长度后输出位置。默认10,设为0不输出位置</summary>
public Int32 ShowPositionStep { get { return _ShowPositionStep; } set { _ShowPositionStep = value; } }
#endregion
#region 基本读写方法
/// <summary>写入</summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
public override void Write(byte[] buffer, int offset, int count)
{
RaiseAction("Write", buffer, offset, count);
BaseStream.Write(buffer, offset, count);
}
/// <summary>写入一个字节</summary>
/// <param name="value"></param>
public override void WriteByte(byte value)
{
RaiseAction("WriteByte", value);
BaseStream.WriteByte(value);
}
/// <summary>读取</summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
/// <returns></returns>
public override int Read(byte[] buffer, int offset, int count)
{
Int32 n = BaseStream.Read(buffer, offset, count);
RaiseAction("Read", buffer, offset, count, n);
return n;
}
/// <summary>读取一个字节</summary>
/// <returns></returns>
public override int ReadByte()
{
Int32 n = BaseStream.ReadByte();
RaiseAction("ReadByte", n);
return n;
}
#endregion
#region 异步读写方法
/// <summary>异步开始读</summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
/// <param name="callback"></param>
/// <param name="state"></param>
/// <returns></returns>
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
RaiseAction("BeginRead", offset, count);
return BaseStream.BeginRead(buffer, offset, count, callback, state);
}
/// <summary>异步开始写</summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
/// <param name="callback"></param>
/// <param name="state"></param>
/// <returns></returns>
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
RaiseAction("BeginWrite", offset, count);
return BaseStream.BeginWrite(buffer, offset, count, callback, state);
}
/// <summary>异步读结束</summary>
/// <param name="asyncResult"></param>
/// <returns></returns>
public override int EndRead(IAsyncResult asyncResult)
{
RaiseAction("EndRead");
return BaseStream.EndRead(asyncResult);
}
/// <summary>异步写结束</summary>
/// <param name="asyncResult"></param>
public override void EndWrite(IAsyncResult asyncResult)
{
RaiseAction("EndWrite");
BaseStream.EndWrite(asyncResult);
}
#endregion
#region 其它方法
/// <summary>设置流位置</summary>
/// <param name="offset"></param>
/// <param name="origin"></param>
/// <returns></returns>
public override long Seek(long offset, SeekOrigin origin)
{
RaiseAction("Seek", offset, origin);
return BaseStream.Seek(offset, origin);
}
/// <summary>关闭数据流</summary>
public override void Close()
{
RaiseAction("Close");
BaseStream.Close();
}
/// <summary>刷新缓冲区</summary>
public override void Flush()
{
RaiseAction("Flush");
BaseStream.Flush();
}
/// <summary>设置长度</summary>
/// <param name="value"></param>
public override void SetLength(long value)
{
RaiseAction("SetLength", value);
BaseStream.SetLength(value);
}
#endregion
#region 属性
/// <summary>可读</summary>
public override bool CanRead { get { return BaseStream.CanRead; } }
/// <summary>可搜索</summary>
public override bool CanSeek { get { return BaseStream.CanSeek; } }
/// <summary>可超时</summary>
public override bool CanTimeout { get { return BaseStream.CanTimeout; } }
/// <summary>可写</summary>
public override bool CanWrite { get { return BaseStream.CanWrite; } }
/// <summary>可读</summary>
public override int ReadTimeout { get { return BaseStream.ReadTimeout; } set { BaseStream.ReadTimeout = value; } }
/// <summary>读写超时</summary>
public override int WriteTimeout { get { return base.WriteTimeout; } set { base.WriteTimeout = value; } }
/// <summary>长度</summary>
public override long Length { get { return BaseStream.Length; } }
/// <summary>位置</summary>
public override long Position
{
get { return BaseStream.Position; }
set
{
RaiseAction("SetPosition", value);
BaseStream.Position = value;
}
}
#endregion
#region 构造
/// <summary>实例化跟踪流</summary>
public TraceStream() : this(null) { }
/// <summary>实例化跟踪流</summary>
/// <param name="stream"></param>
public TraceStream(Stream stream)
{
if (stream == null) stream = new MemoryStream();
BaseStream = stream;
UseConsole = true;
}
#endregion
#region 事件
/// <summary>操作时触发</summary>
public event EventHandler<EventArgs<String, Object[]>> OnAction;
Int64 lastPosition = -1;
void RaiseAction(String action, params Object[] args)
{
if (OnAction != null)
{
if (_TraceMembers != null && !_TraceMembers.Contains(action)) return;
if (ShowPositionStep > 0)
{
var cp = Position;
if (lastPosition < 0)
{
lastPosition = cp;
OnAction(this, new EventArgs<string, object[]>("BeginPosition", new Object[] { lastPosition }));
}
if (cp > lastPosition + ShowPositionStep)
{
lastPosition = cp;
OnAction(this, new EventArgs<string, object[]>("Position", new Object[] { lastPosition }));
}
}
OnAction(this, new EventArgs<string, object[]>(action, args));
}
}
#endregion
#region 控制台
private Boolean _UseConsole;
/// <summary>是否使用控制台</summary>
public Boolean UseConsole
{
get { return _UseConsole; }
set
{
//if (value && !Runtime.IsConsole) throw new InvalidOperationException("非控制台程序无法使用该功能!");
if (value && !Runtime.IsConsole) return;
if (value == _UseConsole) return;
if (value)
OnAction += new EventHandler<EventArgs<string, object[]>>(TraceStream_OnAction);
else
OnAction -= new EventHandler<EventArgs<string, object[]>>(TraceStream_OnAction);
_UseConsole = value;
}
}
private Encoding _Encoding = Encoding.UTF8;
/// <summary>编码</summary>
public Encoding Encoding { get { return _Encoding; } set { _Encoding = value; } }
void TraceStream_OnAction(object sender, EventArgs<string, object[]> e)
{
ConsoleColor color = Console.ForegroundColor;
// 红色动作
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(e.Arg1);
// 白色十六进制
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\t");
Byte[] buffer = null;
Int32 offset = 0;
Int32 count = 0;
if (e.Arg2.Length > 1)
{
if (e.Arg2[0] is Byte[]) buffer = (Byte[])e.Arg2[0];
offset = (Int32)e.Arg2[1];
count = (Int32)e.Arg2[e.Arg2.Length - 1];
}
if (e.Arg2.Length == 1)
{
Int32 n = Convert.ToInt32(e.Arg2[0]);
// 大于10才显示十进制
if (n >= 10)
Console.Write("{0:X2} ({0})", n);
else
Console.Write("{0:X2}", n);
}
else if (buffer != null)
{
if (count == 1)
{
//Console.Write("{0:X2} ({0})", Convert.ToInt32(buffer[0]));
Int32 n = Convert.ToInt32(buffer[0]);
// 大于10才显示十进制
if (n >= 10)
Console.Write("{0:X2} ({0})", n);
else
Console.Write("{0:X2}", n);
}
else
Console.Write(BitConverter.ToString(buffer, offset, count <= 50 ? count : 50) + (count <= 50 ? "" : "...(共" + count + ")"));
}
// 黄色内容
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("\t");
if (e.Arg2.Length == 1)
{
//Int32 n = Convert.ToInt32(e.Arg2[0]);
////if (n >= 0) Console.Write(Convert.ToChar(n));
//// 只显示可见字符
//if (n >= '0') Console.Write(Convert.ToChar(n));
if (e.Arg2[0] != null)
{
TypeCode tc = Type.GetTypeCode(e.Arg2[0].GetType());
//if (tc >= TypeCode.Int16 && tc <= TypeCode.UInt64)
if (tc != TypeCode.Object)
{
Console.Write(e.Arg2[0]);
}
}
}
else if (buffer != null)
{
if (count == 1)
{
//Console.Write("{0} ({1})", Convert.ToChar(buffer[0]), Convert.ToInt32(buffer[0]));
// 只显示可见字符
if (buffer[0] >= '0') Console.Write("{0} ({1})", Convert.ToChar(buffer[0]), Convert.ToInt32(buffer[0]));
}
else if (count == 2)
Console.Write(BitConverter.ToInt16(Format(buffer), offset));
else if (count == 4)
Console.Write(BitConverter.ToInt32(Format(buffer), offset));
else if (count < 50)
Console.Write(Encoding.GetString(buffer, offset, count));
}
Console.ForegroundColor = color;
Console.WriteLine();
}
Byte[] Format(Byte[] buffer)
{
if (buffer == null || buffer.Length < 1) return buffer;
if (IsLittleEndian) return buffer;
// 不要改变原来的数组
//Array.Reverse(buffer);
var bts = new Byte[buffer.Length];
Buffer.BlockCopy(buffer, 0, bts, 0, bts.Length);
Array.Reverse(bts);
return bts;
}
#endregion
}
}
|