using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace Public
{
public unsafe class BufferPip
{
public static int DefaultSize = 1024;
internal byte[] Buffer;
protected int m_Read = 0;
protected int m_Write = 0;
public BufferPip()
: this(DefaultSize)
{
}
public BufferPip(int bufferSize)
{
Buffer = new Byte[bufferSize];
}
public BufferPip(byte[] bf)
{
Buffer = bf;
m_Read = 0;
m_Write = bf.Length;
}
public int OffsetGet
{
get { return m_Read; }
}
public BufferPip CopyDeep()
{
int len = this.Buffer.Length;
BufferPip pip = new BufferPip(len);
System.Buffer.BlockCopy(this.Buffer, 0, pip.Buffer, 0, len);
pip.m_Read = this.m_Read;
pip.m_Write = this.m_Write;
return pip;
}
public BufferPip CopyUsable()
{
int len = this.Count;
BufferPip pip = new BufferPip(len);
System.Buffer.BlockCopy(this.Buffer, m_Read, pip.Buffer, 0, len);
pip.m_Read = 0;
pip.m_Write = len;
return pip;
}
public BufferPip CopyUsable(byte[] addFront)
{
int len = this.Count;
len += addFront.Length;
BufferPip rT = new BufferPip(len);
rT.Write(addFront);
rT.Write(this);
return rT;
}
public BufferPip(byte[] bf, int offset, int count)
{
Buffer = bf;
m_Read = offset;
m_Write = count;
}
/// <summary>
/// 向当前读取位置之前插入数据,如果空间不够,那么将有效数据后移
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="structure"></param>
public void Insert<T>(ref T structure)
{
int writePos;
int size = Marshal.SizeOf(typeof(T));
if (m_Read < size)
{
int copyLen = this.Count;
System.Buffer.BlockCopy(this.Buffer, m_Read, this.Buffer, size, copyLen);
writePos = 0;
m_Read = 0;
m_Write = size + copyLen;
}
else
writePos = m_Read - size;
fixed (byte* p = Buffer)
{
IntPtr aP = new IntPtr(p + writePos);
Marshal.StructureToPtr(structure, aP, true);
}
}
/// <summary>
/// 忽略asci2编码 40以下的控制字符
/// </summary>
public void SkipChar40()
{
for (int i = this.m_Read; i < this.m_Write; i++)
{
if(this.Buffer[i] >= 40)
{
this.m_Read = i;
return;
}
}
this.Clear();
}
public void Read(MMAPSegment mms, int len)
{//从buffer中读取len到MMAPSegment
mms.Write(this.Buffer,m_Read,len);
m_Read += len;
}
public void Read<T>(out T structure) //where T : struct
{
fixed (byte* p = Buffer)
{
IntPtr inP = new IntPtr(p+m_Read);
structure = (T)Marshal.PtrToStructure(inP, typeof(T));
m_Read += Marshal.SizeOf(typeof(T));
}
}
/// <summary>
/// 需要对数据进行二次处理时设置。
/// begin是要重复使用数据的开始位置。
/// </summary>
/// <param name="begin"></param>
public void SetReUse(int begin, int end)
{
m_Write = end;
m_Read = begin;
}
/// <summary>
/// 不改变结束位置,将开始位置重置。
/// </summary>
/// <param name="pos"></param>
public void ReSetRead(int pos)
{
m_Read = pos;
}
public void FetchJoin(IList<ArraySegment<byte>> AS)
{
AS.Add(new ArraySegment<byte>(this.Buffer, this.m_Read, this.Count));
}
public int FetchInt(int pos)
{
return BitConverter.ToInt32(Buffer, pos);
}
public void Fetch(BufferPip pip, int len)
{
pip.Write(this.Buffer, this.m_Read, len);
}
public void FetchLast(BufferPip pip, int len)
{
int readBegin = this.m_Write - len;
if (readBegin < m_Read)
throw new Exception("Buffer Data Overflow -zero");
pip.Write(this.Buffer, readBegin, len);
}
/// <summary>
/// 判断缓冲区的内容是否相等64位
/// </summary>
/// <returns></returns>
public bool IsSame(BufferPip pip, int len)
{
return IsSame(pip.Buffer, pip.m_Read, len);
}
/// <summary>
/// 判断缓冲区的内容是否相等64位
/// </summary>
public bool IsSame(byte[] value, int offset, int len)
{
fixed (byte* p1 = this.Buffer)
fixed (byte* p2 = value)
{
return MMAPSegment.MemeryCompare(p1, p2, len) == IntPtr.Zero;
}
}
public bool IsSame(IntPtr p, int len)
{
byte* t = (byte*)p.ToPointer();
fixed (byte* f = this.Buffer)
{
return MMAPSegment.MemeryCompare(t, f, len) == IntPtr.Zero;
}
}
public int BufferSize
{
get { return Buffer.Length; }
}
static void BufferWritOverFlow(BufferPip bp)
{
throw new Exception("BUffer WriteOverflow");
}
public bool IsOverReaded
{
get { return m_Read > m_Write; }
}
public int Count
{
get
{
return m_Write - m_Read;
}
}
//剩余可写空间
public int FreeSpace
{
get
{
return Buffer.Length - m_Write;//m_Read的空余空间必须在LeftZero后才可使用。
}
}
public void Clear()
{
m_Read = 0;
m_Write = 0;
}
//把有效数据左移动
public void LeftZero()
{
int now = Count;
if (now > 0)
System.Buffer.BlockCopy(Buffer, m_Read, Buffer, 0, now);
m_Read = 0;
m_Write = now;
}
void OnInitialReadEnd(IAsyncResult aIR)
{
object[] param = aIR.AsyncState as object[];
Stream aS = param[0] as Stream;
Action<BufferPip> callBack = param[1] as Action<BufferPip>;
int readed = aS.EndRead(aIR);
m_Write = readed;
callBack(this);
}
public void SkipToEnd(int toEndLen)
{
m_Read = m_Write - toEndLen;
}
public void SkipWrite(int len)
{
this.m_Write += len;
}
public void Write(MMAPSegment mms, int len)
{
mms.Read(this.Buffer, 0, len);
m_Write += len;
}
public void Write(MMAPSegment mms, uint len)
{
this.Write(mms, (int)len);
}
public void Write(BufferPip pip)
{
pip.ReadToBuffer(this);
}
public void Write(byte[] data, int offset, int len)
{
System.Buffer.BlockCopy(data, offset, Buffer, m_Write, len);
m_Write += len;
}
public void Write(byte[] data)
{
Write(data, 0, data.Length);
}
public void WriteWithClose(Stream aS,int len,Action<BufferPip, Exception> callback)
{
aS.BeginWrite(this.Buffer, m_Read, len, (ir) => {
try
{
aS.EndWrite(ir);
if (callback != null)
callback(this, null);
}
catch(Exception ef)
{
if(callback != null)
callback(this,ef);
}
finally
{
aS.Close();
aS.Dispose();
}
}, null);
}
//同步读取流数据
public void WriteStream(Stream aS, int len)
{
aS.Read(this.Buffer, m_Write, len);
m_Write += len;
}
public void WriteAsync(Stream aS, Action<BufferPip,Exception> callback)
{
WriteAsync(aS, this.FreeSpace, callback);
}
public void WriteAsyncOnce(Stream aS, Action<BufferPip,Exception> callback)
{
int maxlen =this.FreeSpace;
aS.BeginRead(this.Buffer, m_Read, maxlen, (air) =>
{
int len = aS.EndRead(air);
if (len <= 0)
{
callback(this, new Exception("流接收端未正常结束,请检查发送端代码。"));
return;
}
m_Write += len;
callback(this, null);
}, null);
}
class DataSender
{
public BufferPip pip;
public int Length;
public Action<BufferPip, Exception> CB;
public Stream Stream;
public void WriteFullCallBack(IAsyncResult air)
{
try
{
DataSender ds = air.AsyncState as DataSender;
int wlen = ds.Stream.EndRead(air);
pip.m_Read += wlen;
int askedMore = ds.Length - pip.m_Read;
if (wlen <= 0)
{//读取失败
ds.CB(this.pip, new Exception("写入0长度内容"));
return;
}
if (askedMore > 0)
{//还需要读取数据
this.Stream.BeginRead(pip.Buffer, pip.m_Read, askedMore, this.WriteFullCallBack, this);
}
else
{//完成读取
pip.m_Write += wlen;
this.CB(this.pip, null);
}
}
catch (Exception ed)
{
try { this.CB(this.pip, ed); }
catch { }
}
}
}
public void WriteFullAsync(Stream aS, int len, Action<BufferPip, Exception> callback)
{
var obj = new DataSender{pip=this,Length = len, CB = callback, Stream = aS };
aS.BeginRead(this.Buffer, m_Read, len, obj.WriteFullCallBack, obj);
}
public void WriteAsync(Stream aS, int len, Action<BufferPip,Exception> callback)
{//不考虑溢出,读取len个字符到buffer
try
{
aS.BeginRead(this.Buffer, m_Read, len, (aIR) =>
{
try
{
int wlen = aS.EndRead(aIR);
int askedMore = len - wlen;
if (wlen <= 0)
{//读取失败
callback(this, new Exception("写入0长度内容,输入流未完成输入即断开"));
return;
}
else if (askedMore > 0)
{//还需要读取数据
Exception aE = new Exception("写入函数未完全写入即返回,未处理逻辑");
callback(this, aE);
ErrorLog.Current.LogException(1, "bufferPip.WriteAsync", aE);
}
else
{//完成读取
m_Write += len;
callback(this, null);
}
}
catch (Exception e)
{
try
{
callback(this, e);
}
catch (Exception inE)
{
ErrorLog.Current.LogException(1000, "BufferPip.WriteAsync", inE);
}
}
}, null);
}
catch (Exception outE)
{
ErrorLog.Current.LogException(1000, "BufferPip.WriteAsync", outE);
}
}
public void Write(int t)
{
fixed (byte* numRef = Buffer)
{
int* nowPos = (int*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 4;
}
public void Write(uint t)
{
fixed (byte* numRef = Buffer)
{
uint* nowPos = (uint*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 4;
}
public void Write(long[] datas)
{
fixed (byte* numRef = Buffer)
{
for (int i = 0; i < datas.Length; i++)
{
long* nowPos = (long*)(numRef + this.m_Write);
*nowPos = datas[i];
m_Write += 8;
}
}
}
public void Write(long t)
{
fixed (byte* numRef = Buffer)
{
long* nowPos = (long*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 8;
}
public void Write(ulong t)
{
fixed (byte* numRef = Buffer)
{
ulong* nowPos = (ulong*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 8;
}
public void Write(short t)
{
fixed (byte* numRef = Buffer)
{
short* nowPos = (short*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 2;
}
public void Write(ushort t)
{
fixed (byte* numRef = Buffer)
{
ushort* nowPos = (ushort*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 2;
}
public void Write(DateTime t)
{
long time = t.ToUniversalTime().Ticks;
fixed (byte* numRef = Buffer)
{
long* nowPos = (long*)(numRef + this.m_Write);
*nowPos = time;
}
m_Write += 8;
}
public void Write(double t)
{
fixed (byte* numRef = Buffer)
{
double* nowPos = (double*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 8;
}
public void Write(decimal t)
{
fixed (byte* numRef = Buffer)
{
decimal* nowPos = (decimal*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 16;
}
public void Write(float t)
{
fixed (byte* numRef = Buffer)
{
float* nowPos = (float*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 4;
}
public void Write(byte b)
{
Buffer[m_Write++] = b;
}
public void Write(bool b)
{
Buffer[m_Write++] = (b) ? (byte)255 : (byte)0;
}
public int Write<T>(ref T obj)
{
fixed (byte* p = Buffer)
{
IntPtr inp = new IntPtr(p + m_Write);
Marshal.StructureToPtr(obj, inp, true);
int rT = Marshal.SizeOf(typeof(T));
m_Write += rT;
return rT;
}
}
public void WriteArray<T>(T[] data)
{
int rT = Marshal.SizeOf(typeof(T));
fixed (byte* p = Buffer)
{
for (int i = 0; i < data.Length; i++)
{
IntPtr inp = new IntPtr(p + m_Write);
Marshal.StructureToPtr(data[i], inp, true);
m_Write += rT;
}
}
}
/// <summary>
/// 带分割的内容数组
/// </summary>
public void WriteArray<T>(T[] data,ref long sep)
{
int rT = Marshal.SizeOf(typeof(T));
fixed (byte* p = Buffer)
{
for (int i = 0; i < data.Length; i++)
{
IntPtr inp = new IntPtr(p + m_Write);
Marshal.StructureToPtr(data[i], inp, true);
m_Write += rT;
long* nowPos = (long*)(p + this.m_Write);
long toAppend = sep++;
*nowPos = toAppend;
m_Write += 8;
}
}
}
public void Write(IntPtr source, int size)
{
Marshal.Copy(source, this.Buffer, m_Write, size);
m_Write += size;
}
public void WriteString(System.Text.Encoding encode,string info)
{
byte[] byteInfo = encode.GetBytes(info);
this.Write(byteInfo);
}
public void Write(string info, System.Text.Encoding encode)
{
byte[] byteInfo = encode.GetBytes(info);
this.Write(byteInfo);
this.Write((ushort)0);
}
public void SkipRead(int len)
{
m_Read = m_Read + len;
}
public void ReadToIntPtr(IntPtr p, int len)
{
Marshal.Copy(this.Buffer, m_Read, p, len);
m_Read += len;
}
public void ReadToIntPtr(IntPtr p, uint len)
{
ReadToIntPtr(p, (int)len);
}
public void ReadToBuffer(BufferOperat bff)
{
int len = Math.Min(this.Count, bff.FreeSpace);
ReadToBuffer(bff, len);
}
public void ReadToBuffer(BufferOperat bff, int len)
{
bff.Write(this.Buffer,m_Read,len);
}
public void CheckOverFlow()
{
if (this.m_Read > this.m_Write)
throw new Exception("buffer Read Overflow");
}
public byte ReadByte()
{
byte rT = Buffer[m_Read];
m_Read++;
return rT;
}
public short ReadInt16()
{
short i = BitConverter.ToInt16(Buffer, m_Read);
m_Read += 2;
return i;
}
public int ReadInt32()
{
int i = BitConverter.ToInt32(Buffer, m_Read);
m_Read += 4;
return i;
}
public uint ReadUInt32()
{
uint i = BitConverter.ToUInt32(Buffer, m_Read);
m_Read += 4;
return i;
}
public ushort ReadUInt16()
{
ushort i = BitConverter.ToUInt16(Buffer, m_Read);
m_Read += 2;
return i;
}
public long ReadInt64()
{
long rT = BitConverter.ToInt64(Buffer, m_Read);
m_Read += 8;
return rT;
}
public static int SizeOf(Type t)
{
return Marshal.SizeOf(t);
}
public void ReadToStream(Stream outs)
{
outs.Write(Buffer, 0, Buffer.Length);
this.Clear();
}
public void FetchToFile(string path)
{
FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.None);
fs.Write(this.Buffer, m_Read, (m_Write - m_Read));
}
public void FetchToFile(string path,Action<Exception> callback)
{
FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.None);
fs.BeginWrite(this.Buffer, m_Read, (m_Write - m_Read), (airt) =>
{
try
{
fs.EndWrite(airt);
callback(null);
}
catch (Exception e)
{
callback(e);
}
}, null);
}
void NullFunction(Exception e)
{
}
public void FetchToFile(string[] path, Action<Exception> callback)
{
try
{
foreach (string afile in path)
{
this.FetchToFile(afile, NullFunction);
System.Threading.Thread.Sleep(0);//切换线程,降低优先级
}
callback(null);
}
catch (Exception e)
{
callback(e);
}
}
class streamTransfer
{
public Stream sin;
public Stream sout;
public int askLen;
int ReadedLen=0;
int lastsendCount;
public BufferPip pip;
public Action<BufferPip, Exception> callback;
public void DoCallBack(Exception e)
{
if (askLen == int.MaxValue)
{
sin.Dispose();
sin.Close();
sout.Dispose();
sout.Close();
}
callback(pip, e);
}
public void DoTransfer()
{
try
{
if (pip.Count > 0)
{
lastsendCount = Math.Min(askLen, pip.Count);
sout.BeginWrite(pip.Buffer, pip.m_Read, lastsendCount, OutDataEnded, null);
}
else
{
pip.Clear();
sin.BeginRead(pip.Buffer, pip.m_Write, pip.FreeSpace, DoReadEnded, null);
}
}
catch (Exception e)
{
DoCallBack(e);
}
}
void OutDataEnded(IAsyncResult air)
{
try
{
sout.EndWrite(air);
ReadedLen += lastsendCount;//已经转移完成的字节数
int needRead = askLen - ReadedLen;
if (needRead <= 0)
{//发送完成
pip.m_Read += lastsendCount;
DoCallBack(null);
return;
}
else
{
pip.Clear();
sin.BeginRead(pip.Buffer, pip.m_Write,pip.Buffer.Length, DoReadEnded, null);
}
}
catch (Exception e)
{
DoCallBack(e);
}
}
void DoReadEnded(IAsyncResult air)
{
try
{
int len = sin.EndRead(air);
pip.m_Write += len;
if (len == 0)
{
if (this.askLen == int.MaxValue)
{
DoCallBack(null);
}
else
{
DoCallBack(new Exception("非正常的流结束时间,从源数据读取时失败"));
}
return;
}
lastsendCount = Math.Min((askLen - ReadedLen), pip.Count);
sout.BeginWrite(pip.Buffer, pip.m_Read, lastsendCount, OutDataEnded, null);
}
catch (Exception e)
{
DoCallBack(e);
}
}
}
/// <summary>
/// 连接两个stream,把当前缓冲区内的数据+sin中的数据 转移tranLen字节长度 到 sout.
/// sin可能会多读取数据到缓冲区
/// </summary>
/// <param name="sin"></param>
/// <param name="sout"></param>
/// <param name="tranLen"></param>
public void StreamAnsycConnect(Stream si, Stream sou, int tranLen, Action<BufferPip, Exception> callback)
{
streamTransfer st = new streamTransfer() { sin = si, sout = sou, pip = this, askLen = tranLen, callback = callback };
st.DoTransfer();
}
//读取输入流,保存到输出流,直到输入流结束
public void StreamHttpcConnect(Stream si, Stream sou,Action<BufferPip, Exception> callback)
{
streamTransfer st = new streamTransfer() { sin = si, sout = sou, pip = this, askLen = int.MaxValue, callback = callback };
st.DoTransfer();
}
public void ReadToStream(Stream outs,int length)
{
outs.Write(Buffer, 0, length);
m_Read += length;
}
public void ReadToStreamAsync(Stream outs, Action<Exception> callback)
{
ReadStreamAsync(outs, this.Count, callback);
}
/// <summary>
/// 异步写到流,callback不能为空
/// outs不能在callback完成之前销毁
/// </summary>
public void ReadStreamAsync(Stream outs, int len, Action<Exception> callback)
{
outs.BeginWrite(this.Buffer, m_Read, len, (aIR) =>
{
try
{
outs.EndWrite(aIR);
callback(null);
}
catch(Exception ed)
{
callback(ed);
}
}, null);
m_Read += len;//无论是否发送成功,都当作已经发送。
}
public static bool IsRNFoure(System.Text.Encoding encode)
{
return encode.GetBytes("\r\n").Length == 4;
}
public static void SetInt64(byte[] bf, int offset, long value)
{
fixed (byte* p = bf)
{
*(long*)(p + offset) = value;
}
}
public static void SetInt32(byte[] bf, int offset, int value)
{
fixed (byte* p = bf)
{
*(int*)(p + offset) = value;
}
}
public string ReadStringAbsolut(System.Text.Encoding encode, int bufStart, int bufEnd)
{
return encode.GetString(this.Buffer, bufStart, (bufEnd - bufStart));
}
public void ReadToFindEnd(byte[] end,out int bufBegin,out int bufEnd)
{
bufBegin = -1;
bufEnd = -1;
int tofind = BitConverter.ToInt32(end, 0);
fixed (byte* p = this.Buffer)
fixed(byte* cmp = end)
{
byte* begin = p + this.m_Read;
int nowEnd = 0;
while (true)
{
if (nowEnd + m_Read + 4 > m_Write)
return;
byte* nowP = begin + nowEnd;
if (tofind == (*((int*)(nowP))))
{
if (MemeryCompare(nowP, cmp, end.Length))
{
bufBegin = m_Read;
m_Read = m_Read + nowEnd + end.Length;
bufEnd = m_Read;
return;
}
}
nowEnd++;
}
}
}
public static bool MemeryCompare(byte* pi,byte* p2,int len)
{
int pos = 0;
while ( len - pos >= 8)
{
if ((*(long*)(pi + pos)) != (*(long*)(p2 + pos)))
return false;
pos += 8;
}
for (int i = pos; i < len; i++)
{
if (pi[i] != p2[i])
return false;
}
return true;
}
public string ReadString(System.Text.Encoding encode)
{
return this.ReadString(encode, this.Count);
}
public string ReadString(System.Text.Encoding encode, int len)
{
string rT = encode.GetString(Buffer, m_Read, len);
m_Read += len;
return rT;
}
int FindNextLong(long l)
{
fixed (byte* p = this.Buffer)
{
byte* begin = p + this.m_Read;
int nowEnd = 0;//m_Read之后的偏移量
while (true)
{
if (nowEnd + m_Read + 8 > m_Write)
return -1;
if (l == (*((long*)(begin + nowEnd))))
{
return nowEnd;
}
nowEnd++;
}
}
}
int FindNextInt(int tofind)
{//返回以m_read为0的偏移量
fixed (byte* p = this.Buffer)
{
byte* begin = p + this.m_Read;
int nowEnd = 0;
while (true)
{
if (nowEnd + m_Read + 4 > m_Write)
return -1;
if (tofind == (*((int*)(begin + nowEnd))))
{
return nowEnd;
}
nowEnd++;
}
}
}
int FindNextByte(byte t)
{
fixed (byte* p = this.Buffer)
{//避免越界检查
byte* begin = p + this.m_Read;
int rt = 0;
while (true)
{
if (rt + m_Read == m_Write)
return -1;
if (t == *(begin + rt))
return rt;
rt++;
}
}
}
int FindNextShort(short toFind)
{
fixed (byte* p = this.Buffer)
{
byte* begin = p + this.m_Read;
int nowEnd = 0;
while (true)
{
if (nowEnd + m_Read + 2 > m_Write)
return -1;
if (toFind == (*((short*)(begin + nowEnd))))
{
return nowEnd;
}
nowEnd++;
}
}
}
//使用绝对定位获得字符串值
public string GetAbsolutString(System.Text.Encoding en,int begin,int end)
{
return en.GetString(this.Buffer, begin, (end - begin));
}
public int IndexLenOf(byte[] data, int offset)
{
fixed (byte* src = this.Buffer)
fixed (byte* tar = data)
{
int maxEnd = m_Write-data.Length;
for (int i = offset; i < maxEnd; i++)
{
for (int j = 0; j < data.Length; j++)
{
if (Buffer[i + j] != data[j])
goto ToContine;
}
return i;
ToContine:
continue;
}
}
return -1;
}
public int IndexLenOf(byte[] data)
{
int rt;
if (data == null || data.Length == 0)
{
rt = -1;
}
else
{
switch (data.Length)
{
case 1: rt = this.FindNextByte(data[0]); break;
case 2: rt = this.FindNextShort(BitConverter.ToInt16(data, 0)); break;
case 4: rt = this.FindNextInt(BitConverter.ToInt32(data, 0)); break;
case 8: rt = this.FindNextLong(BitConverter.ToInt64(data, 0)); break;
default:
if (data.Length > 8)
{
long l = BitConverter.ToInt64(data, 0);
fixed (byte* p = this.Buffer)
{
byte* begin = p + this.m_Read;
rt = 0;
while (true)
{
LoopBegin:
if (rt + m_Read + 8 > m_Write)
{
rt = -1;
break;
}
if (l == (*((long*)(begin + rt))))
{
for (int i = 4; i < data.Length; i++)
{//long相同的概率非常低,这里不考虑优化。
if (data[i] != *(begin + rt + i))
{
goto LoopBegin;
}
}
goto LoopOut;
}
rt++;
}
LoopOut:
;
}
}
else
throw new Exception("不支持的长度");
break;
}
}
if (rt < 0)
return rt;
return rt;
}
/// <summary>
/// 返回说明:
/// string 发现一个\r\n
/// "" 有连续的\r\n
/// null 没有结束的\r\n,但缓冲区可能还有数据。
/// </summary>
public string ReadLine(System.Text.Encoding encode, bool rnFoure)
{
int offset;
if (rnFoure)
{//4字节 回车换行
offset = FindNextInt(655373);
}
else
{//2字节 回车换行
offset = FindNextShort(2573);
}
if (offset < 0)
return null;
int readBegin = m_Read;
m_Read = m_Read + offset;
if (rnFoure)
m_Read += 4;
else
m_Read += 2;
return encode.GetString(Buffer, readBegin, offset);
}
/// <summary>
/// 将本对象的缓冲区设置到SocketAsyncEventArgs上
/// </summary>
/// <param name="e"></param>
public void ReadSocketBufferFull(System.Net.Sockets.SocketAsyncEventArgs e)
{
this.LeftZero();
e.SetBuffer(this.Buffer, m_Write, this.FreeSpace);
}
public void SendSocetBufferFull(System.Net.Sockets.SocketAsyncEventArgs e)
{
e.SetBuffer(this.Buffer, m_Read, this.Count);
}
public void WriteSoket(System.Net.Sockets.Socket s, Action<BufferPip, System.Net.Sockets.SocketAsyncEventArgs> callback)
{
System.Net.Sockets.SocketAsyncEventArgs received
= new System.Net.Sockets.SocketAsyncEventArgs();
received.SetBuffer(this.Buffer,m_Write,this.FreeSpace);
received.UserToken = callback;
received.Completed -= OnSocketDataReceived;
received.Completed -= OnSocketDataReceived;
received.Completed += OnSocketDataReceived;
if (!s.ReceiveAsync(received))
{
OnSocketDataReceived(s, received);
}
}
void OnSocketDataReceived(object sender,System.Net.Sockets.SocketAsyncEventArgs e)
{
m_Write += e.BytesTransferred;
Action<BufferPip, System.Net.Sockets.SocketAsyncEventArgs>
cb = e.UserToken as Action<BufferPip, System.Net.Sockets.SocketAsyncEventArgs>;
cb(this, e);
this.LeftZero();
if (e.BytesTransferred > 0)
{
System.Net.Sockets.Socket s = sender as System.Net.Sockets.Socket;
if (!s.ReceiveAsync(e))
{
OnSocketDataReceived(s, e);
}
}
}
public void ReadToSocket(System.Net.Sockets.Socket s,int len)
{
s.BeginSend(this.Buffer, m_Read, len, System.Net.Sockets.SocketFlags.None, null, null);
m_Read += len;
}
}
}
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace Public
{
public unsafe class BufferPip
{
public static int DefaultSize = 1024;
internal byte[] Buffer;
protected int m_Read = 0;
protected int m_Write = 0;
public BufferPip()
: this(DefaultSize)
{
}
public BufferPip(int bufferSize)
{
Buffer = new Byte[bufferSize];
}
public BufferPip(byte[] bf)
{
Buffer = bf;
m_Read = 0;
m_Write = bf.Length;
}
public int OffsetGet
{
get { return m_Read; }
}
public BufferPip CopyDeep()
{
int len = this.Buffer.Length;
BufferPip pip = new BufferPip(len);
System.Buffer.BlockCopy(this.Buffer, 0, pip.Buffer, 0, len);
pip.m_Read = this.m_Read;
pip.m_Write = this.m_Write;
return pip;
}
public BufferPip CopyUsable()
{
int len = this.Count;
BufferPip pip = new BufferPip(len);
System.Buffer.BlockCopy(this.Buffer, m_Read, pip.Buffer, 0, len);
pip.m_Read = 0;
pip.m_Write = len;
return pip;
}
public BufferPip CopyUsable(byte[] addFront)
{
int len = this.Count;
len += addFront.Length;
BufferPip rT = new BufferPip(len);
rT.Write(addFront);
rT.Write(this);
return rT;
}
public BufferPip(byte[] bf, int offset, int count)
{
Buffer = bf;
m_Read = offset;
m_Write = count;
}
/// <summary>
/// 向当前读取位置之前插入数据,如果空间不够,那么将有效数据后移
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="structure"></param>
public void Insert<T>(ref T structure)
{
int writePos;
int size = Marshal.SizeOf(typeof(T));
if (m_Read < size)
{
int copyLen = this.Count;
System.Buffer.BlockCopy(this.Buffer, m_Read, this.Buffer, size, copyLen);
writePos = 0;
m_Read = 0;
m_Write = size + copyLen;
}
else
writePos = m_Read - size;
fixed (byte* p = Buffer)
{
IntPtr aP = new IntPtr(p + writePos);
Marshal.StructureToPtr(structure, aP, true);
}
}
/// <summary>
/// 忽略asci2编码 40以下的控制字符
/// </summary>
public void SkipChar40()
{
for (int i = this.m_Read; i < this.m_Write; i++)
{
if(this.Buffer[i] >= 40)
{
this.m_Read = i;
return;
}
}
this.Clear();
}
public void Read(MMAPSegment mms, int len)
{//从buffer中读取len到MMAPSegment
mms.Write(this.Buffer,m_Read,len);
m_Read += len;
}
public void Read<T>(out T structure) //where T : struct
{
fixed (byte* p = Buffer)
{
IntPtr inP = new IntPtr(p+m_Read);
structure = (T)Marshal.PtrToStructure(inP, typeof(T));
m_Read += Marshal.SizeOf(typeof(T));
}
}
/// <summary>
/// 需要对数据进行二次处理时设置。
/// begin是要重复使用数据的开始位置。
/// </summary>
/// <param name="begin"></param>
public void SetReUse(int begin, int end)
{
m_Write = end;
m_Read = begin;
}
/// <summary>
/// 不改变结束位置,将开始位置重置。
/// </summary>
/// <param name="pos"></param>
public void ReSetRead(int pos)
{
m_Read = pos;
}
public void FetchJoin(IList<ArraySegment<byte>> AS)
{
AS.Add(new ArraySegment<byte>(this.Buffer, this.m_Read, this.Count));
}
public int FetchInt(int pos)
{
return BitConverter.ToInt32(Buffer, pos);
}
public void Fetch(BufferPip pip, int len)
{
pip.Write(this.Buffer, this.m_Read, len);
}
public void FetchLast(BufferPip pip, int len)
{
int readBegin = this.m_Write - len;
if (readBegin < m_Read)
throw new Exception("Buffer Data Overflow -zero");
pip.Write(this.Buffer, readBegin, len);
}
/// <summary>
/// 判断缓冲区的内容是否相等64位
/// </summary>
/// <returns></returns>
public bool IsSame(BufferPip pip, int len)
{
return IsSame(pip.Buffer, pip.m_Read, len);
}
/// <summary>
/// 判断缓冲区的内容是否相等64位
/// </summary>
public bool IsSame(byte[] value, int offset, int len)
{
fixed (byte* p1 = this.Buffer)
fixed (byte* p2 = value)
{
return MMAPSegment.MemeryCompare(p1, p2, len) == IntPtr.Zero;
}
}
public bool IsSame(IntPtr p, int len)
{
byte* t = (byte*)p.ToPointer();
fixed (byte* f = this.Buffer)
{
return MMAPSegment.MemeryCompare(t, f, len) == IntPtr.Zero;
}
}
public int BufferSize
{
get { return Buffer.Length; }
}
static void BufferWritOverFlow(BufferPip bp)
{
throw new Exception("BUffer WriteOverflow");
}
public bool IsOverReaded
{
get { return m_Read > m_Write; }
}
public int Count
{
get
{
return m_Write - m_Read;
}
}
//剩余可写空间
public int FreeSpace
{
get
{
return Buffer.Length - m_Write;//m_Read的空余空间必须在LeftZero后才可使用。
}
}
public void Clear()
{
m_Read = 0;
m_Write = 0;
}
//把有效数据左移动
public void LeftZero()
{
int now = Count;
if (now > 0)
System.Buffer.BlockCopy(Buffer, m_Read, Buffer, 0, now);
m_Read = 0;
m_Write = now;
}
void OnInitialReadEnd(IAsyncResult aIR)
{
object[] param = aIR.AsyncState as object[];
Stream aS = param[0] as Stream;
Action<BufferPip> callBack = param[1] as Action<BufferPip>;
int readed = aS.EndRead(aIR);
m_Write = readed;
callBack(this);
}
public void SkipToEnd(int toEndLen)
{
m_Read = m_Write - toEndLen;
}
public void SkipWrite(int len)
{
this.m_Write += len;
}
public void Write(MMAPSegment mms, int len)
{
mms.Read(this.Buffer, 0, len);
m_Write += len;
}
public void Write(MMAPSegment mms, uint len)
{
this.Write(mms, (int)len);
}
public void Write(BufferPip pip)
{
pip.ReadToBuffer(this);
}
public void Write(byte[] data, int offset, int len)
{
System.Buffer.BlockCopy(data, offset, Buffer, m_Write, len);
m_Write += len;
}
public void Write(byte[] data)
{
Write(data, 0, data.Length);
}
public void WriteWithClose(Stream aS,int len,Action<BufferPip, Exception> callback)
{
aS.BeginWrite(this.Buffer, m_Read, len, (ir) => {
try
{
aS.EndWrite(ir);
if (callback != null)
callback(this, null);
}
catch(Exception ef)
{
if(callback != null)
callback(this,ef);
}
finally
{
aS.Close();
aS.Dispose();
}
}, null);
}
//同步读取流数据
public void WriteStream(Stream aS, int len)
{
aS.Read(this.Buffer, m_Write, len);
m_Write += len;
}
public void WriteAsync(Stream aS, Action<BufferPip,Exception> callback)
{
WriteAsync(aS, this.FreeSpace, callback);
}
public void WriteAsyncOnce(Stream aS, Action<BufferPip,Exception> callback)
{
int maxlen =this.FreeSpace;
aS.BeginRead(this.Buffer, m_Read, maxlen, (air) =>
{
int len = aS.EndRead(air);
if (len <= 0)
{
callback(this, new Exception("流接收端未正常结束,请检查发送端代码。"));
return;
}
m_Write += len;
callback(this, null);
}, null);
}
class DataSender
{
public BufferPip pip;
public int Length;
public Action<BufferPip, Exception> CB;
public Stream Stream;
public void WriteFullCallBack(IAsyncResult air)
{
try
{
DataSender ds = air.AsyncState as DataSender;
int wlen = ds.Stream.EndRead(air);
pip.m_Read += wlen;
int askedMore = ds.Length - pip.m_Read;
if (wlen <= 0)
{//读取失败
ds.CB(this.pip, new Exception("写入0长度内容"));
return;
}
if (askedMore > 0)
{//还需要读取数据
this.Stream.BeginRead(pip.Buffer, pip.m_Read, askedMore, this.WriteFullCallBack, this);
}
else
{//完成读取
pip.m_Write += wlen;
this.CB(this.pip, null);
}
}
catch (Exception ed)
{
try { this.CB(this.pip, ed); }
catch { }
}
}
}
public void WriteFullAsync(Stream aS, int len, Action<BufferPip, Exception> callback)
{
var obj = new DataSender{pip=this,Length = len, CB = callback, Stream = aS };
aS.BeginRead(this.Buffer, m_Read, len, obj.WriteFullCallBack, obj);
}
public void WriteAsync(Stream aS, int len, Action<BufferPip,Exception> callback)
{//不考虑溢出,读取len个字符到buffer
try
{
aS.BeginRead(this.Buffer, m_Read, len, (aIR) =>
{
try
{
int wlen = aS.EndRead(aIR);
int askedMore = len - wlen;
if (wlen <= 0)
{//读取失败
callback(this, new Exception("写入0长度内容,输入流未完成输入即断开"));
return;
}
else if (askedMore > 0)
{//还需要读取数据
Exception aE = new Exception("写入函数未完全写入即返回,未处理逻辑");
callback(this, aE);
ErrorLog.Current.LogException(1, "bufferPip.WriteAsync", aE);
}
else
{//完成读取
m_Write += len;
callback(this, null);
}
}
catch (Exception e)
{
try
{
callback(this, e);
}
catch (Exception inE)
{
ErrorLog.Current.LogException(1000, "BufferPip.WriteAsync", inE);
}
}
}, null);
}
catch (Exception outE)
{
ErrorLog.Current.LogException(1000, "BufferPip.WriteAsync", outE);
}
}
public void Write(int t)
{
fixed (byte* numRef = Buffer)
{
int* nowPos = (int*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 4;
}
public void Write(uint t)
{
fixed (byte* numRef = Buffer)
{
uint* nowPos = (uint*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 4;
}
public void Write(long[] datas)
{
fixed (byte* numRef = Buffer)
{
for (int i = 0; i < datas.Length; i++)
{
long* nowPos = (long*)(numRef + this.m_Write);
*nowPos = datas[i];
m_Write += 8;
}
}
}
public void Write(long t)
{
fixed (byte* numRef = Buffer)
{
long* nowPos = (long*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 8;
}
public void Write(ulong t)
{
fixed (byte* numRef = Buffer)
{
ulong* nowPos = (ulong*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 8;
}
public void Write(short t)
{
fixed (byte* numRef = Buffer)
{
short* nowPos = (short*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 2;
}
public void Write(ushort t)
{
fixed (byte* numRef = Buffer)
{
ushort* nowPos = (ushort*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 2;
}
public void Write(DateTime t)
{
long time = t.ToUniversalTime().Ticks;
fixed (byte* numRef = Buffer)
{
long* nowPos = (long*)(numRef + this.m_Write);
*nowPos = time;
}
m_Write += 8;
}
public void Write(double t)
{
fixed (byte* numRef = Buffer)
{
double* nowPos = (double*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 8;
}
public void Write(decimal t)
{
fixed (byte* numRef = Buffer)
{
decimal* nowPos = (decimal*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 16;
}
public void Write(float t)
{
fixed (byte* numRef = Buffer)
{
float* nowPos = (float*)(numRef + this.m_Write);
*nowPos = t;
}
m_Write += 4;
}
public void Write(byte b)
{
Buffer[m_Write++] = b;
}
public void Write(bool b)
{
Buffer[m_Write++] = (b) ? (byte)255 : (byte)0;
}
public int Write<T>(ref T obj)
{
fixed (byte* p = Buffer)
{
IntPtr inp = new IntPtr(p + m_Write);
Marshal.StructureToPtr(obj, inp, true);
int rT = Marshal.SizeOf(typeof(T));
m_Write += rT;
return rT;
}
}
public void WriteArray<T>(T[] data)
{
int rT = Marshal.SizeOf(typeof(T));
fixed (byte* p = Buffer)
{
for (int i = 0; i < data.Length; i++)
{
IntPtr inp = new IntPtr(p + m_Write);
Marshal.StructureToPtr(data[i], inp, true);
m_Write += rT;
}
}
}
/// <summary>
/// 带分割的内容数组
/// </summary>
public void WriteArray<T>(T[] data,ref long sep)
{
int rT = Marshal.SizeOf(typeof(T));
fixed (byte* p = Buffer)
{
for (int i = 0; i < data.Length; i++)
{
IntPtr inp = new IntPtr(p + m_Write);
Marshal.StructureToPtr(data[i], inp, true);
m_Write += rT;
long* nowPos = (long*)(p + this.m_Write);
long toAppend = sep++;
*nowPos = toAppend;
m_Write += 8;
}
}
}
public void Write(IntPtr source, int size)
{
Marshal.Copy(source, this.Buffer, m_Write, size);
m_Write += size;
}
public void WriteString(System.Text.Encoding encode,string info)
{
byte[] byteInfo = encode.GetBytes(info);
this.Write(byteInfo);
}
public void Write(string info, System.Text.Encoding encode)
{
byte[] byteInfo = encode.GetBytes(info);
this.Write(byteInfo);
this.Write((ushort)0);
}
public void SkipRead(int len)
{
m_Read = m_Read + len;
}
public void ReadToIntPtr(IntPtr p, int len)
{
Marshal.Copy(this.Buffer, m_Read, p, len);
m_Read += len;
}
public void ReadToIntPtr(IntPtr p, uint len)
{
ReadToIntPtr(p, (int)len);
}
public void ReadToBuffer(BufferOperat bff)
{
int len = Math.Min(this.Count, bff.FreeSpace);
ReadToBuffer(bff, len);
}
public void ReadToBuffer(BufferOperat bff, int len)
{
bff.Write(this.Buffer,m_Read,len);
}
public void CheckOverFlow()
{
if (this.m_Read > this.m_Write)
throw new Exception("buffer Read Overflow");
}
public byte ReadByte()
{
byte rT = Buffer[m_Read];
m_Read++;
return rT;
}
public short ReadInt16()
{
short i = BitConverter.ToInt16(Buffer, m_Read);
m_Read += 2;
return i;
}
public int ReadInt32()
{
int i = BitConverter.ToInt32(Buffer, m_Read);
m_Read += 4;
return i;
}
public uint ReadUInt32()
{
uint i = BitConverter.ToUInt32(Buffer, m_Read);
m_Read += 4;
return i;
}
public ushort ReadUInt16()
{
ushort i = BitConverter.ToUInt16(Buffer, m_Read);
m_Read += 2;
return i;
}
public long ReadInt64()
{
long rT = BitConverter.ToInt64(Buffer, m_Read);
m_Read += 8;
return rT;
}
public static int SizeOf(Type t)
{
return Marshal.SizeOf(t);
}
public void ReadToStream(Stream outs)
{
outs.Write(Buffer, 0, Buffer.Length);
this.Clear();
}
public void FetchToFile(string path)
{
FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.None);
fs.Write(this.Buffer, m_Read, (m_Write - m_Read));
}
public void FetchToFile(string path,Action<Exception> callback)
{
FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.None);
fs.BeginWrite(this.Buffer, m_Read, (m_Write - m_Read), (airt) =>
{
try
{
fs.EndWrite(airt);
callback(null);
}
catch (Exception e)
{
callback(e);
}
}, null);
}
void NullFunction(Exception e)
{
}
public void FetchToFile(string[] path, Action<Exception> callback)
{
try
{
foreach (string afile in path)
{
this.FetchToFile(afile, NullFunction);
System.Threading.Thread.Sleep(0);//切换线程,降低优先级
}
callback(null);
}
catch (Exception e)
{
callback(e);
}
}
class streamTransfer
{
public Stream sin;
public Stream sout;
public int askLen;
int ReadedLen=0;
int lastsendCount;
public BufferPip pip;
public Action<BufferPip, Exception> callback;
public void DoCallBack(Exception e)
{
if (askLen == int.MaxValue)
{
sin.Dispose();
sin.Close();
sout.Dispose();
sout.Close();
}
callback(pip, e);
}
public void DoTransfer()
{
try
{
if (pip.Count > 0)
{
lastsendCount = Math.Min(askLen, pip.Count);
sout.BeginWrite(pip.Buffer, pip.m_Read, lastsendCount, OutDataEnded, null);
}
else
{
pip.Clear();
sin.BeginRead(pip.Buffer, pip.m_Write, pip.FreeSpace, DoReadEnded, null);
}
}
catch (Exception e)
{
DoCallBack(e);
}
}
void OutDataEnded(IAsyncResult air)
{
try
{
sout.EndWrite(air);
ReadedLen += lastsendCount;//已经转移完成的字节数
int needRead = askLen - ReadedLen;
if (needRead <= 0)
{//发送完成
pip.m_Read += lastsendCount;
DoCallBack(null);
return;
}
else
{
pip.Clear();
sin.BeginRead(pip.Buffer, pip.m_Write,pip.Buffer.Length, DoReadEnded, null);
}
}
catch (Exception e)
{
DoCallBack(e);
}
}
void DoReadEnded(IAsyncResult air)
{
try
{
int len = sin.EndRead(air);
pip.m_Write += len;
if (len == 0)
{
if (this.askLen == int.MaxValue)
{
DoCallBack(null);
}
else
{
DoCallBack(new Exception("非正常的流结束时间,从源数据读取时失败"));
}
return;
}
lastsendCount = Math.Min((askLen - ReadedLen), pip.Count);
sout.BeginWrite(pip.Buffer, pip.m_Read, lastsendCount, OutDataEnded, null);
}
catch (Exception e)
{
DoCallBack(e);
}
}
}
/// <summary>
/// 连接两个stream,把当前缓冲区内的数据+sin中的数据 转移tranLen字节长度 到 sout.
/// sin可能会多读取数据到缓冲区
/// </summary>
/// <param name="sin"></param>
/// <param name="sout"></param>
/// <param name="tranLen"></param>
public void StreamAnsycConnect(Stream si, Stream sou, int tranLen, Action<BufferPip, Exception> callback)
{
streamTransfer st = new streamTransfer() { sin = si, sout = sou, pip = this, askLen = tranLen, callback = callback };
st.DoTransfer();
}
//读取输入流,保存到输出流,直到输入流结束
public void StreamHttpcConnect(Stream si, Stream sou,Action<BufferPip, Exception> callback)
{
streamTransfer st = new streamTransfer() { sin = si, sout = sou, pip = this, askLen = int.MaxValue, callback = callback };
st.DoTransfer();
}
public void ReadToStream(Stream outs,int length)
{
outs.Write(Buffer, 0, length);
m_Read += length;
}
public void ReadToStreamAsync(Stream outs, Action<Exception> callback)
{
ReadStreamAsync(outs, this.Count, callback);
}
/// <summary>
/// 异步写到流,callback不能为空
/// outs不能在callback完成之前销毁
/// </summary>
public void ReadStreamAsync(Stream outs, int len, Action<Exception> callback)
{
outs.BeginWrite(this.Buffer, m_Read, len, (aIR) =>
{
try
{
outs.EndWrite(aIR);
callback(null);
}
catch(Exception ed)
{
callback(ed);
}
}, null);
m_Read += len;//无论是否发送成功,都当作已经发送。
}
public static bool IsRNFoure(System.Text.Encoding encode)
{
return encode.GetBytes("\r\n").Length == 4;
}
public static void SetInt64(byte[] bf, int offset, long value)
{
fixed (byte* p = bf)
{
*(long*)(p + offset) = value;
}
}
public static void SetInt32(byte[] bf, int offset, int value)
{
fixed (byte* p = bf)
{
*(int*)(p + offset) = value;
}
}
public string ReadStringAbsolut(System.Text.Encoding encode, int bufStart, int bufEnd)
{
return encode.GetString(this.Buffer, bufStart, (bufEnd - bufStart));
}
public void ReadToFindEnd(byte[] end,out int bufBegin,out int bufEnd)
{
bufBegin = -1;
bufEnd = -1;
int tofind = BitConverter.ToInt32(end, 0);
fixed (byte* p = this.Buffer)
fixed(byte* cmp = end)
{
byte* begin = p + this.m_Read;
int nowEnd = 0;
while (true)
{
if (nowEnd + m_Read + 4 > m_Write)
return;
byte* nowP = begin + nowEnd;
if (tofind == (*((int*)(nowP))))
{
if (MemeryCompare(nowP, cmp, end.Length))
{
bufBegin = m_Read;
m_Read = m_Read + nowEnd + end.Length;
bufEnd = m_Read;
return;
}
}
nowEnd++;
}
}
}
public static bool MemeryCompare(byte* pi,byte* p2,int len)
{
int pos = 0;
while ( len - pos >= 8)
{
if ((*(long*)(pi + pos)) != (*(long*)(p2 + pos)))
return false;
pos += 8;
}
for (int i = pos; i < len; i++)
{
if (pi[i] != p2[i])
return false;
}
return true;
}
public string ReadString(System.Text.Encoding encode)
{
return this.ReadString(encode, this.Count);
}
public string ReadString(System.Text.Encoding encode, int len)
{
string rT = encode.GetString(Buffer, m_Read, len);
m_Read += len;
return rT;
}
int FindNextLong(long l)
{
fixed (byte* p = this.Buffer)
{
byte* begin = p + this.m_Read;
int nowEnd = 0;//m_Read之后的偏移量
while (true)
{
if (nowEnd + m_Read + 8 > m_Write)
return -1;
if (l == (*((long*)(begin + nowEnd))))
{
return nowEnd;
}
nowEnd++;
}
}
}
int FindNextInt(int tofind)
{//返回以m_read为0的偏移量
fixed (byte* p = this.Buffer)
{
byte* begin = p + this.m_Read;
int nowEnd = 0;
while (true)
{
if (nowEnd + m_Read + 4 > m_Write)
return -1;
if (tofind == (*((int*)(begin + nowEnd))))
{
return nowEnd;
}
nowEnd++;
}
}
}
int FindNextByte(byte t)
{
fixed (byte* p = this.Buffer)
{//避免越界检查
byte* begin = p + this.m_Read;
int rt = 0;
while (true)
{
if (rt + m_Read == m_Write)
return -1;
if (t == *(begin + rt))
return rt;
rt++;
}
}
}
int FindNextShort(short toFind)
{
fixed (byte* p = this.Buffer)
{
byte* begin = p + this.m_Read;
int nowEnd = 0;
while (true)
{
if (nowEnd + m_Read + 2 > m_Write)
return -1;
if (toFind == (*((short*)(begin + nowEnd))))
{
return nowEnd;
}
nowEnd++;
}
}
}
//使用绝对定位获得字符串值
public string GetAbsolutString(System.Text.Encoding en,int begin,int end)
{
return en.GetString(this.Buffer, begin, (end - begin));
}
public int IndexLenOf(byte[] data, int offset)
{
fixed (byte* src = this.Buffer)
fixed (byte* tar = data)
{
int maxEnd = m_Write-data.Length;
for (int i = offset; i < maxEnd; i++)
{
for (int j = 0; j < data.Length; j++)
{
if (Buffer[i + j] != data[j])
goto ToContine;
}
return i;
ToContine:
continue;
}
}
return -1;
}
public int IndexLenOf(byte[] data)
{
int rt;
if (data == null || data.Length == 0)
{
rt = -1;
}
else
{
switch (data.Length)
{
case 1: rt = this.FindNextByte(data[0]); break;
case 2: rt = this.FindNextShort(BitConverter.ToInt16(data, 0)); break;
case 4: rt = this.FindNextInt(BitConverter.ToInt32(data, 0)); break;
case 8: rt = this.FindNextLong(BitConverter.ToInt64(data, 0)); break;
default:
if (data.Length > 8)
{
long l = BitConverter.ToInt64(data, 0);
fixed (byte* p = this.Buffer)
{
byte* begin = p + this.m_Read;
rt = 0;
while (true)
{
LoopBegin:
if (rt + m_Read + 8 > m_Write)
{
rt = -1;
break;
}
if (l == (*((long*)(begin + rt))))
{
for (int i = 4; i < data.Length; i++)
{//long相同的概率非常低,这里不考虑优化。
if (data[i] != *(begin + rt + i))
{
goto LoopBegin;
}
}
goto LoopOut;
}
rt++;
}
LoopOut:
;
}
}
else
throw new Exception("不支持的长度");
break;
}
}
if (rt < 0)
return rt;
return rt;
}
/// <summary>
/// 返回说明:
/// string 发现一个\r\n
/// "" 有连续的\r\n
/// null 没有结束的\r\n,但缓冲区可能还有数据。
/// </summary>
public string ReadLine(System.Text.Encoding encode, bool rnFoure)
{
int offset;
if (rnFoure)
{//4字节 回车换行
offset = FindNextInt(655373);
}
else
{//2字节 回车换行
offset = FindNextShort(2573);
}
if (offset < 0)
return null;
int readBegin = m_Read;
m_Read = m_Read + offset;
if (rnFoure)
m_Read += 4;
else
m_Read += 2;
return encode.GetString(Buffer, readBegin, offset);
}
/// <summary>
/// 将本对象的缓冲区设置到SocketAsyncEventArgs上
/// </summary>
/// <param name="e"></param>
public void ReadSocketBufferFull(System.Net.Sockets.SocketAsyncEventArgs e)
{
this.LeftZero();
e.SetBuffer(this.Buffer, m_Write, this.FreeSpace);
}
public void SendSocetBufferFull(System.Net.Sockets.SocketAsyncEventArgs e)
{
e.SetBuffer(this.Buffer, m_Read, this.Count);
}
public void WriteSoket(System.Net.Sockets.Socket s, Action<BufferPip, System.Net.Sockets.SocketAsyncEventArgs> callback)
{
System.Net.Sockets.SocketAsyncEventArgs received
= new System.Net.Sockets.SocketAsyncEventArgs();
received.SetBuffer(this.Buffer,m_Write,this.FreeSpace);
received.UserToken = callback;
received.Completed -= OnSocketDataReceived;
received.Completed -= OnSocketDataReceived;
received.Completed += OnSocketDataReceived;
if (!s.ReceiveAsync(received))
{
OnSocketDataReceived(s, received);
}
}
void OnSocketDataReceived(object sender,System.Net.Sockets.SocketAsyncEventArgs e)
{
m_Write += e.BytesTransferred;
Action<BufferPip, System.Net.Sockets.SocketAsyncEventArgs>
cb = e.UserToken as Action<BufferPip, System.Net.Sockets.SocketAsyncEventArgs>;
cb(this, e);
this.LeftZero();
if (e.BytesTransferred > 0)
{
System.Net.Sockets.Socket s = sender as System.Net.Sockets.Socket;
if (!s.ReceiveAsync(e))
{
OnSocketDataReceived(s, e);
}
}
}
public void ReadToSocket(System.Net.Sockets.Socket s,int len)
{
s.BeginSend(this.Buffer, m_Read, len, System.Net.Sockets.SocketFlags.None, null, null);
m_Read += len;
}
}
}